package cc.linker.steplink.crm.merchanth5.service.impl;

import cc.linker.steplink.crm.commons.BeanMapUtils;
import cc.linker.steplink.crm.commons.CrmRedisKeys;
import cc.linker.steplink.crm.commons.FeeConstants;
import cc.linker.steplink.crm.commons.TradeTypeConstants;
import cc.linker.steplink.crm.commons.constant.DongConstant;
import cc.linker.steplink.crm.commons.constant.TlPayConstant;
import cc.linker.steplink.crm.commons.constant.WcPayConstant;
import cc.linker.steplink.crm.commons.coupon.CouponCustomerInfo;
import cc.linker.steplink.crm.commons.http.HttpService;
import cc.linker.steplink.crm.commons.lock.LettuceLock;
import cc.linker.steplink.crm.commons.model.SystemProperties;
import cc.linker.steplink.crm.commons.model.WcPayProperties;
import cc.linker.steplink.crm.commons.service.CommonsService;
import cc.linker.steplink.crm.commons.utils.NumberUtils;
import cc.linker.steplink.crm.commons.utils.TransactionOrderUtil;
import cc.linker.steplink.crm.merchanth5.controller.acs.MerchantSalerController;
import cc.linker.steplink.crm.merchanth5.dao.*;
import cc.linker.steplink.crm.merchanth5.dao.acs.*;
import cc.linker.steplink.crm.merchanth5.model.OrderAddressDto;
import cc.linker.steplink.crm.merchanth5.pojo.*;
import cc.linker.steplink.crm.merchanth5.pojo.acs.AccountInfo;
import cc.linker.steplink.crm.merchanth5.pojo.acs.TradeInfo;
import cc.linker.steplink.crm.merchanth5.pojo.coupon.CouponGoodsPo;
import cc.linker.steplink.crm.merchanth5.service.*;
import cc.linker.steplink.crm.merchanth5.service.acs.MerchantSalerService;
import cc.linker.steplink.crm.merchanth5.service.acs.PromoterClueService;
import cc.linker.steplink.crm.merchanth5.service.acs.PurchaseProcessNewService;
import cc.linker.steplink.crm.merchanth5.service.acs.PurchaseProcessService;
import cc.linker.steplink.crm.merchanth5.service.common.SmsService;
import cc.linker.steplink.crm.merchanth5.service.coupon.CouponH5Service;
import cc.linker.steplink.crm.merchanth5.service.coupon.H5IsLossGoodsService;
import cc.linker.steplink.crm.merchanth5.service.integral.IntegralH5Service;
import cc.linker.steplink.crm.merchanth5.service.redis.GoodsService;
import cc.linker.steplink.crm.merchanth5.service.tl.LedgerProcessService;
import cc.linker.steplink.crm.merchanth5.util.ParamSignUtils;
import cc.linker.steplink.crm.response.GlobalException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URISyntaxException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@EnableAsync
@Service
public class PurchaseProcessServiceImpl implements PurchaseProcessService {

    // 锁
    public static final String ACS_CREATE_ORDER_LOCK = "ACS:CREATE_ORDER_LOCK";

    // 锁
    public static final String REFUND_ORDER_LOCK = "refund:REFUND_ORDER_LOCK";

    // 分账信息
    public static final String ACS_CREATE_ORDER_INFO = "ACS:CREATE_ORDER_INFO";

    // 调用返回结果
    public static final String ACS_CREATE_ORDER_RESULT = "ACS:CREATE_ORDER_RESULT";

    // 上下级关系
    public static final String ACS_CREATE_ORDER_SUBORDINATE = "ACS:CREATE_ORDER_SUBORDINATE";

    // 商品分享链路id
    public static final String ACS_CREATE_ORDER_LINK_ID = "ACS:CREATE_ORDER_LINK_ID";

    private static final DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    public String payStatusKey = "paystatus:payorder_";

    private String LUA_SCRIPT =
            "local buyNum = tonumber(ARGV[1])\n" +
                    "local goodsKey = KEYS[1]  \n" +
                    "local goodsNum = tonumber(redis.call('get',goodsKey)) \n" +
                    "if goodsNum >= buyNum \n" +
                    "then redis.call('decrby',goodsKey,buyNum) \n" +
                    "return 1 \n" +
                    "else \n" +
                    "return 0\n" +
                    "end\n" +
                    "\n";
    @Autowired
    private PurchaseProcessNewService purchaseProcessNewService;

    @Value("${system.scrm.acsScrmWebUrl}")
    private String scrmH5Url;
    @Value("${casclient.clientHost}")
    private String clientHost;
    @Autowired
    private MallDao mallDao;
    @Autowired
    private MallService mallService;
    @Autowired
    private MallBoomDao mallBoomDao;
    @Autowired
    private HttpService httpService;
    @Autowired
    private LettuceLock lettuceLock;
    @Autowired
    private SystemProperties systemProperties;
    @Autowired
    private WcPayProperties wcPayProperties;
    @Autowired
    private PurchaseProcessDao purchaseProcessDao;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private MallBoomService mallBoomService;
    @Autowired
    private MerchantSalerService merchantSalerService;
    @Autowired
    private MerchantSalerController merchantSalerController;
    @Autowired
    private MaiBaoLaService maiBaoLaService;
    @Lazy
    @Autowired
    private EnrollActiveService enrollActiveService;
    @Autowired
    private ColumnDao columnDao;
    @Autowired
    private SmsService smsService;
    @Autowired
    private ColumnService columnService;
    @Autowired
    private MerchantSalerDao merchantSalerDao;
    @Autowired
    private WxShareDao wxShareDao;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private WithdrawTaskDao withdrawTaskDao;
    @Autowired
    private MerchantWalletDao merchantWalletDao;
    @Autowired
    private LedgerProcessService ledgerProcessService;
    @Autowired
    private CommonsService commonsService;
    @Autowired
    private ProtectRecordDao protectRecordDao;
    @Autowired
    private VipCustomerLogDao vipCustomerLogDao;
    @Autowired
    private VipCustomerLogService vipCustomerLogService;
    @Autowired
    private IntegralH5Service integralH5Service;
    @Autowired
    private CouponH5Service couponH5Service;
    @Autowired
    private H5IsLossGoodsService h5IsLossGoodsService;
    @Autowired
    private PromoterClueService promoterClueService;
    @Autowired
    private DataSourceTransactionManager txManager;
    @Value("${system.scrm.maxCreateOrderNum}")
    private int maxCreateOrderNum;
    @Value("${system.scrm.maxCreateOrderTime}")
    private int maxCreateOrderTime;

    /**
     * 确认订单
     */
//    @Override
//    public CheckMerchantOrderPo checkOrder(Map<String, Object> param) {
//        String customerId = (String) param.get("customerId");
//        String orgId = (String) param.get("orgId");
//        // 剩余积分
//        Integer score = purchaseProcessDao.getScoreByCustomerId(customerId);
//        Integer goodsId = null;
//        Integer buyCount = (Integer) param.get("buyCount");
//        //商户id
//        Long merchantId;
//        if (param.containsKey("goodsId") && param.get("goodsId") != null) {
//            goodsId = Integer.valueOf(param.get("goodsId").toString());
//            Integer quota = maiBaoLaService.quota(goodsId.toString(), customerId);
//            if (buyCount > quota && quota != -1) {
//                String goodsName = purchaseProcessDao.getGoodsNameByGoodsId(goodsId.toString());
//                throw GlobalException.build(goodsName + "商品超过了限购上限");
//            }
//            merchantId = mallDao.getMerchantIdByGoodsId(goodsId.toString());
//        }
//        String shoppingCartIds = (String) param.get("shoppingCartIds");
//        Integer goodsNum = 0;
//        double goodsAmount = 0.00;
//        Double orderAmount = 0.00;
//        Double orderTotalPrice = 0.00;
//        Double goodsFreight = 0.00;
//        List<ShoppingCartPo> shoppingCartPos;
//        CheckMerchantOrderPo orderPo = new CheckMerchantOrderPo();
//        orderPo.setScore(score);
//        orderPo.setScoreAble(score);
//        List<ShoppingCartGoodsPo> goodsPoList = new ArrayList<>();
//        // 3+4
//        Map<String, String> platformRateMap = purchaseProcessDao.getPlatformRateByOrgId(orgId);
//        Double linkerTake = Double.valueOf(platformRateMap.get("linkerTake"));
//        Double unionBarleyTake = Double.valueOf(platformRateMap.get("unionBarleyTake"));
//        Double platformRate = linkerTake + unionBarleyTake;
//        if (goodsId != null && goodsId != 0 && buyCount != null && buyCount != 0) {
//            // 直接购买联盟商家的商品，需要计算最大可抵扣积分
//            ShoppingCartGoodsPo goodsPo = mallDao.checkShoppingGoodsOrder(param);
//            if(goodsPo==null){
//                throw GlobalException.build("商品失效，请重新下单!");
//            }
//            goodsPo.setBuyCount(buyCount);
//            goodsNum = goodsNum + goodsPo.getBuyCount();
//            goodsAmount = goodsAmount + goodsPo.getAmount() * goodsPo.getBuyCount();
//            orderAmount = orderAmount + goodsPo.getAmount() * goodsPo.getBuyCount();
//            orderTotalPrice = orderTotalPrice + goodsPo.getAmount() * goodsPo.getBuyCount();
//            goodsFreight = goodsPo.getGoodsFreight();
//
//            if (StringUtils.isEmpty(goodsPo.getBelongId()) && (int) param.get("type") != 1) {
//                orderPo.setType(1);
////                Integer total = (int) ((orderTotalPrice + goodsFreight) * 100);
////                if (score > total) {
////                    orderPo.setScoreAble(total);
////                }
//            } else {
//                orderPo.setType(0);
//            }
//            // 需要计算
//            // 总
//            double total = (orderTotalPrice + goodsFreight) * 100;
//            // 商
//            double shop = orderTotalPrice * 100;
//            // 根据计算，需要实付金额不小于（1.推荐费+2.服务费+3.平台抽成+4.大麦抽成）
//            // 1+2
//            String rebateStr = purchaseProcessDao.getPromotionStrRebateByGoodsId(goodsId.longValue());
//            Double rebate = Double.valueOf(rebateStr);
//            // 计算
//            double v = total - (shop * rebate) / (100 - platformRate);
//            // 可用积分只舍不入
//            int i = (int) v;
//            if (score > i) {
//                orderPo.setScoreAble(i);
//            }
//            goodsPoList.add(goodsPo);
//        } else if (!StringUtils.isEmpty(shoppingCartIds)) {
//            // 购物车购买
//            orderPo.setType(1);
//            String[] split = shoppingCartIds.split(",");
//            param.put("shoppingCartIds", split);
//            shoppingCartPos = mallDao.checkShoppingCartOrder(param);
//            for (ShoppingCartPo cartPo : shoppingCartPos) {
//                for (ShoppingCartGoodsPo goodsPo : cartPo.getGoodsList()) {
//                    Integer quota = maiBaoLaService.quota(goodsPo.getGoodsId().toString(), customerId);
//                    if (goodsPo.getBuyCount() > quota && quota != -1) {
//                        throw GlobalException.build(goodsPo.getGoodsName() + "商品超过了限购上限");
//                    }
//                    goodsNum = goodsNum + goodsPo.getBuyCount();
//                    goodsAmount = goodsAmount + goodsPo.getAmount() * goodsPo.getBuyCount();
//                    orderAmount = orderAmount + goodsPo.getAmount() * goodsPo.getBuyCount();
//                    orderTotalPrice = orderTotalPrice + goodsPo.getAmount() * goodsPo.getBuyCount();
////                    if (goodsPo.getGoodsFreight() > goodsFreight) {//取运费最大
//                    goodsFreight += goodsPo.getGoodsFreight();
////                    }
//                    if (!StringUtils.isEmpty(goodsPo.getBelongId())) {
//                        orderPo.setType(0);
//                    }
//                }
//            }
//            if (shoppingCartPos.size() > 0) {
//                goodsPoList = shoppingCartPos.get(0).getGoodsList();
//            }
//            double v = (orderTotalPrice + goodsFreight) * 100;
//            if (score > v) {
//                // 可用积分不超过订单总金额
//                orderPo.setScoreAble((int) v);
//            }
//            double v = (orderTotalPrice + goodsFreight) * 100;
//            if (score > v) {
//                // 可用积分不超过订单总金额
//                orderPo.setScoreAble((int) v);
//        }
//        }
//        orderTotalPrice = orderTotalPrice + goodsFreight;
//        orderAmount = orderAmount + goodsFreight;
//        orderPo.setGoodsAmount(new BigDecimal(goodsAmount).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
//        orderPo.setOrderAmount(new BigDecimal(orderAmount).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
//        orderPo.setOrderTotalPrice(new BigDecimal(orderTotalPrice).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
//        orderPo.setGoodsNum(goodsNum);
//        orderPo.setShippingFee(new BigDecimal(goodsFreight).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
//        if (goodsPoList.size() > 0) {
//            orderPo.setGoodsList(goodsPoList);
//        }
//        return orderPo;
//    }
    @Override
    public Map<String, Object> getCustomerInfoByCustomerId(String customerId) {
        return purchaseProcessDao.getCustomerInfoByCustomerId(customerId);
    }

    /**
     * 创建订单
     */
    @Override
    public Map createOrder(Map<String, Object> param) throws GlobalException, UnsupportedEncodingException {
        LOGGER.info("createOrder-----start");
        String createkey = "{order}create_order";//下单限流key
        Boolean globalLimitByLua = commonsService.getGlobalLimitByLua(createkey, maxCreateOrderTime, maxCreateOrderNum);
        if (!globalLimitByLua) {
            LOGGER.info("createOrder---活动太火爆了");
            throw GlobalException.goodsFiery();
        }

        OrderAddressDto orderAddressDto = new OrderAddressDto();
        if (!StringUtils.isEmpty(param.get("addressId")) && "-1".equals(param.get("addressId").toString())) {
            //#{addressId}, #{address.realName}, #{address.phone},
            //    #{address.provinceName}, #{address.cityName}, #{address.areaName}, #{address.addressInfo}
            orderAddressDto.setAddressId(-1L);
            orderAddressDto.setRealName(param.get("nickName").toString());
            Map<String, Object> customerInfoByCustomer = mallBoomDao.getCustomerInfoByCustomerId(param.get("customerId").toString());
            orderAddressDto.setPhone(customerInfoByCustomer.get("bindPhone").toString());
            orderAddressDto.setProvinceName("浙江省");
            orderAddressDto.setCityName("衢州市");
            orderAddressDto.setAreaName("龙游县");
            orderAddressDto.setAddressInfo("龙游南海旅行社，龙洲路231-239号");
        } else {
            // 获取地址
            orderAddressDto = mallDao.getDefaultReceiveAddress(param);
        }
        // 用户id
        String customerId = (String) param.get("customerId");
        // 机构id
        String orgId = (String) param.get("orgId");
        // 分享人id
        String distributor = (String) param.get("distributor");
        // 商铺id
        String storeId = (String) param.get("storeId");
        // endregion
        // 只针对用户上了锁，后期可以优化
        //  region 锁，单个用户同一个时间只能下一个单，防止刷单
        String lockKey = ACS_CREATE_ORDER_LOCK + customerId;
        String requestId = UUID.randomUUID().toString();
        boolean lock = lettuceLock.tryLock(lockKey, requestId, 2, TimeUnit.MINUTES);
        if (!lock) {
            throw GlobalException.build("请勿重复购买");
        }

        // endregion
        try {
            // 商品id
            String goodsId = (String) param.get("goodsId");
            // 购物车id
            String shoppingCartIds = "";
            List<Map> couponMapList = new ArrayList<>();
            if (!StringUtils.isEmpty(param.get("orderList"))) {
                List<Map<String, Object>> shoppingCartOrderList = (List) param.get("orderList");
                for (Map<String, Object> so : shoppingCartOrderList) {
                    String couponId = "";
                    String consumptionId = "";
                    if (StringUtils.isEmpty(shoppingCartIds)) {
                        shoppingCartIds = so.get("shoppingCartIds").toString();
                    } else {
                        shoppingCartIds = shoppingCartIds + "," + so.get("shoppingCartIds").toString();
                    }
                    if (!StringUtils.isEmpty(so.get("couponId"))) {
                        couponId = so.get("couponId").toString();
                    }
                    if (!StringUtils.isEmpty(so.get("consumptionId"))) {
                        consumptionId = so.get("consumptionId").toString();
                    }
                    if (!StringUtils.isEmpty(couponId) && !StringUtils.isEmpty(consumptionId)) {
                        Map couponMap = new HashMap();
                        couponMap.put("shoppingCartIds", so.get("shoppingCartIds").toString());
                        couponMap.put("couponId", couponId);
                        couponMap.put("consumptionId", consumptionId);
                        couponMapList.add(couponMap);
                    }
                }
            }
            // 订单sn
            String orderSn = (String) param.get("orderSn");
            //支付订单号
            String paySn = orderSn;
            // 订单总金额order、商品总金额goods，单位：分，若为小b商品则有goodsId
            Map<String, Object> totalFee;
            // 订单id的list(其实理论上只有一个)
            List<Long> orderIds = new ArrayList<>();
            // 是否为支付未支付订单
            boolean rePay = false;
            if (!param.containsKey("orderSource")) {
                param.put("orderSource", "1");
            }
            String orderSource = param.get("orderSource").toString();
            String orderSourcePay = "";
            //根据paySn查询订单来源
            if (!StringUtils.isEmpty(paySn)) {
                orderSourcePay = purchaseProcessDao.getOrderSource(paySn);
                if (!orderSource.equals(orderSourcePay)) {
                    String oldPaySn = paySn;
                    paySn = TransactionOrderUtil.TYPE_SHOP + this.getUniquePrimaryKey();
                    purchaseProcessDao.updatePaySnPayOld(paySn, oldPaySn, orderSource);
                }
            }

            // 生成订单，统计商品价格、订单价格
            if (!StringUtils.isEmpty(goodsId)) {
                //region 这一部分是商品购买
                LOGGER.info("下单进入goodsId方法");
                // 直接购买商品
                // 订单sn
                orderSn = TransactionOrderUtil.TYPE_SHOP + this.getUniquePrimaryKey();
                paySn = orderSn;
                param.put("orderSn", orderSn);
                param.put("paySn", paySn);
                param.put("storeId", storeId);
                // 生成订单
                totalFee = this.insertMerchantOrder(param, orderAddressDto, orderIds, orgId);
                //endregion
            } else if (!StringUtils.isEmpty(shoppingCartIds)) {
                //region 这一部分是购物车下单的函数
                LOGGER.info("下单进入shoppingCartIds方法");
                if (orderAddressDto == null) {
                    //知识付费不需要收货地址
                    throw GlobalException.build("地址不存在或用户与地址不匹配");
                }
                // 购买购物车商品
                paySn = TransactionOrderUtil.TYPE_SHOP + this.getUniquePrimaryKey();
                param.put("paySn", paySn);
                param.put("storeId", storeId);
                LOGGER.info("下单进入shoppingCartIds方法参数：" + JSON.toJSONString(param));

                //事务管理
                DefaultTransactionDefinition def = new DefaultTransactionDefinition();
                def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
                TransactionStatus status = txManager.getTransaction(def);
                // 生成订单
                totalFee = this.insertMerchantOrderByShoppingCart(param, orderAddressDto, orderIds, orgId, couponMapList);
                //取购物车中的第一个分享人
                String[] split = shoppingCartIds.split(",");
                List<String> list = Arrays.asList(split);
                // 删除购物车商品
                for (String shoppingCartId : split) {
                    mallDao.deleteShoppingCartById(Long.parseLong(shoppingCartId));
                }
                txManager.commit(status);
                Map<String, Object> disMap = new HashMap<>();
                disMap.put("shoppingCartIds", list);
                disMap.put("customerId", customerId);
                distributor = mallDao.getShoppingCartDistributor(disMap);
                //endregion 购物车购买结束
            } else if (!StringUtils.isEmpty(paySn)) {
                //region 这一部分是生成过订单进入
                int type = 0;
                // 支付未支付订单
                totalFee = new HashMap<>();
                rePay = true;
                List<Map<String, Object>> signData = new ArrayList<>();
                if (orderSource.equals(orderSourcePay)) {
                    purchaseProcessDao.updatePaySn(paySn);
                }
                List<MerchantOrderPo> orderList = purchaseProcessDao.getMerchantOrderByPayTradeId(paySn);
                LOGGER.info("下单进入paySn方法:orderList->" + JSON.toJSONString(orderList));
                Long goodsAmount = 0L;
                Long orderAmount = 0L;
                List<MerchantOrderGoodsPo> orderGoodsPoList = new ArrayList<>();

                int score = 0;
                for (MerchantOrderPo orderPo : orderList) {
                    orderIds.add(orderPo.getOrderId());
                    goodsAmount += orderPo.getGoodsAmountCent();
                    orderAmount += orderPo.getOrderAmountCent();

                    Map<String, Object> tmpOGMap = new HashMap<>();
                    tmpOGMap.put("orderId", orderPo.getOrderId());
                    List<MerchantOrderGoodsPo> merchantOrderGoodsList = mallDao.getMerchantOrderGoodsList2(tmpOGMap);

                    for (MerchantOrderGoodsPo goodsPo : merchantOrderGoodsList) {
                        MerchantOrderGoodsPo orderGoodsPo = new MerchantOrderGoodsPo();
                        if ("1".equals(goodsPo.getPromotion())) {
                            type = 1;
                        }
                        orderGoodsPo.setCouponAmount(goodsPo.getCouponAmount());
                        orderGoodsPo.setPaymentPoints(goodsPo.getPaymentPoints());
                        orderGoodsPo.setAmountCent(goodsPo.getAmountCent());
                        orderGoodsPo.setCustomerId(customerId);
                        orderGoodsPo.setBuyCount(goodsPo.getBuyCount());
                        orderGoodsPo.setGoodsId(goodsPo.getGoodsId());
                        orderGoodsPo.setGoodsName(goodsPo.getGoodsName());
                        orderGoodsPo.setShippingFee(goodsPo.getShippingFee());
                        orderGoodsPo.setSalerId(goodsPo.getSalerId());
                        orderGoodsPo.setGoodsType(goodsPo.getGoodsType());
                        orderGoodsPo.setRecId(goodsPo.getRecId());
                        orderGoodsPo.setSkuId(goodsPo.getSkuId());
                        orderGoodsPo.setAuthor(goodsPo.getAuthor());
                        orderGoodsPo.setCouponAmount(goodsPo.getCouponAmount());
                        orderGoodsPoList.add(orderGoodsPo);
                    }
                    //组装参数请求签名
                    Map<String, Object> tmpOrderGoods = new HashMap<>();
                    tmpOrderGoods.put("orderSn", orderSn);
                    tmpOrderGoods.put("goodsList", orderGoodsPoList);
                    tmpOrderGoods.put("score", orderPo.getIntegralPaymentAmount());
                    signData.add(tmpOrderGoods);
                    score = score + orderPo.getIntegralPaymentAmount();
                }
                distributor = mallDao.getOrderDistributor(paySn);
                totalFee.put("goods", goodsAmount);
                totalFee.put("order", orderAmount);
                totalFee.put("signData", signData);
                totalFee.put("type", type);
                totalFee.put("score", score);
                //endregion
            } else {
                throw GlobalException.build("参数错误");
            }

            //region app支付用的distributor
            if (!StringUtils.isEmpty(distributor)) {
                stringRedisTemplate.opsForValue().set("appDistributor:" + paySn, distributor, 1, TimeUnit.HOURS);
            }
            //endregion

            // region 是否有上级，如果有需要做上级绑定逻辑
            boolean recommend = false;
            LOGGER.info("上下级参数  customerId---》" + customerId + " distributor--->" + distributor + " type----->" + totalFee.get("type"));
            if (!StringUtils.isEmpty(distributor) && !StringUtils.isEmpty(customerId)) {
                stringRedisTemplate.opsForValue().set("distributor:" + paySn, customerId + "_" + distributor, 1, TimeUnit.HOURS);
            }
            // 商品购买后绑定上下级关系
            if (!StringUtils.isEmpty(customerId) && !StringUtils.isEmpty(distributor) && !customerId.equals(distributor) && 1 == (Integer) totalFee.get("type")) {
                String pidByCid = purchaseProcessDao.getPidByCid(distributor);
                if (customerId.equals(pidByCid)) {
                    distributor = "";
                } else {
                    Map<String, Long> userRole = purchaseProcessDao.getUserRoleMapByCustomerId(distributor);
                    Long c = userRole.get("c");
                    if (c == 1) {
                        String pid = purchaseProcessDao.getPidByCid(customerId);
                        if (StringUtils.isEmpty(pid)) {
                            recommend = true;
                            stringRedisTemplate.opsForValue().set(ACS_CREATE_ORDER_SUBORDINATE + paySn, customerId + "_" + distributor, 1, TimeUnit.HOURS);
                        }
                    }
                }
            }
            //endregion

            // region 内容库商品分享链路id
            String linkId = (String) param.get("linkId");
            if (!StringUtils.isEmpty(linkId)) {
                stringRedisTemplate.opsForValue().set(ACS_CREATE_ORDER_LINK_ID + paySn, linkId, 1, TimeUnit.HOURS);
            }
            //endregion

            // region 免费专栏直接购买
            if (param.get("isKnowledge") != null && param.get("isKnowledge").equals(true)) {
                // 根据id判断商品是否免费，如果免费直接返回
                ShoppingCartGoodsPo goodsPo = mallDao.getShoppingGoodsInfo(param);
                if (goodsPo != null) {
                    Integer goodsType = goodsPo.getGoodsType();
                    if (goodsType == 4) {
                        Map<String, Object> detail = columnDao.getDetail(goodsId, "");
                        Integer isFree = (Integer) detail.get("isFree");
                        if (isFree == 1) {
                            this.zeroBuy(paySn);
                            Map<String, Object> map = new HashMap<>();
                            map.put("status", -2);
                            map.put("orderSn", paySn);
                            return map;
                        }
                    }
                }
            }
            //endregion

            // region 0元商品
            if (!rePay && 0 == Long.valueOf(totalFee.get("order").toString())) {
                this.zeroBuy(paySn);
                Map<String, Object> map = new HashMap<>();
                map.put("status", -2);
                map.put("orderSn", paySn);
                return map;
            }
            //endregion

            // 根据商品和订单价格，以及是否使用积分，计算出钱款流向，组装json后调网关
            // 支付未支付订单，去redis拿签名
            if (param.get("orderSource") == null || "1".equals(param.get("orderSource").toString())) {
                //region 请求微信签名
                List feeList = (List) totalFee.get("signData");
                int score = 0;
                if (!StringUtils.isEmpty(totalFee.get("score"))) {
                    score = Integer.valueOf(totalFee.get("score").toString());
                }
                //请求签名
                return purchaseProcessNewService.getSign(param, paySn, (Integer) param.get("payMode"), feeList, rePay, orgId, score, customerId, orderIds, distributor);
                //endregion
            } else {
                //全额抵扣，请求签名
                if (!StringUtils.isEmpty(totalFee.get("order")) && !StringUtils.isEmpty(totalFee.get("score"))) {
                    int orderAmount = Integer.valueOf(totalFee.get("order").toString());
                    int score = Integer.valueOf(totalFee.get("score").toString());
                    if (orderAmount == score) {
                        List feeList = (List) totalFee.get("signData");
                        param.put("openid", "");
                        return purchaseProcessNewService.getSign(param, paySn, (Integer) param.get("payMode"), feeList, rePay, orgId, score, customerId, orderIds, distributor);
                    }
                }
                //region app来源先返回订单号之后去小程序获取签名
                Map<String, Object> map = new HashMap<>();
                map.put("status", -1);
                map.put("orderSn", paySn);
                return map;
                //endregion
            }
        } finally {
            // 解锁
            lettuceLock.releaseLock(lockKey, requestId);
        }
    }

    @Override
    public Map payOrderByxcx(Map<String, Object> param) {

        //orderSn
        String orderSn, paySn, customerId = "", orgId = "", distributor = "";
        if (param.get("orderSn") == null) {
            throw GlobalException.build("订单号不能为空！");
        } else {
            paySn = param.get("orderSn").toString();
        }

        List<Long> orderIds = new ArrayList<>();
        Map<String, Object> totalFee = new HashMap<>();
        // 是否为支付未支付订单
        boolean rePay = false;
        List<Map<String, Object>> signData = new ArrayList<>();

        List<MerchantOrderPo> orderList = purchaseProcessDao.getMerchantOrderByPayTradeId(paySn);
        Long goodsAmount = 0L;
        Long orderAmount = 0L;
        int allScore = 0;
        for (MerchantOrderPo orderPo : orderList) {
            orderSn = orderPo.getOrderSn();
            List<MerchantOrderGoodsPo> orderGoodsPoList = new ArrayList<>();
            orderIds.add(orderPo.getOrderId());
            goodsAmount += orderPo.getGoodsAmountCent();
            orderAmount += orderPo.getOrderAmountCent();

            Map<String, Object> tmpOGMap = new HashMap<>();
            tmpOGMap.put("orderId", orderPo.getOrderId());
            List<MerchantOrderGoodsPo> merchantOrderGoodsList = mallDao.getMerchantOrderGoodsList2(tmpOGMap);

            for (MerchantOrderGoodsPo goodsPo : merchantOrderGoodsList) {
                MerchantOrderGoodsPo orderGoodsPo = new MerchantOrderGoodsPo();
                orderGoodsPo.setPaymentPoints(goodsPo.getPaymentPoints());
                orderGoodsPo.setCouponAmount(goodsPo.getCouponAmount());

                orderGoodsPo.setAmountCent(goodsPo.getAmountCent());
                orderGoodsPo.setCustomerId(goodsPo.getBuyerId());
                orderGoodsPo.setBuyCount(goodsPo.getBuyCount());
                orderGoodsPo.setGoodsId(goodsPo.getGoodsId());
                orderGoodsPo.setGoodsName(goodsPo.getGoodsName());
                orderGoodsPo.setShippingFee(goodsPo.getShippingFee());
                orderGoodsPo.setSalerId(goodsPo.getSalerId());
                orderGoodsPo.setGoodsType(goodsPo.getGoodsType());
                orderGoodsPo.setRecId(goodsPo.getRecId());
                orderGoodsPo.setSkuId(goodsPo.getSkuId());
                orderGoodsPo.setAuthor(goodsPo.getAuthor());
                orderGoodsPo.setCouponAmount(goodsPo.getCouponAmount());
                orderGoodsPoList.add(orderGoodsPo);
                customerId = goodsPo.getBuyerId();
                orgId = goodsPo.getOrgId();
            }
            //组装参数请求签名
            Map<String, Object> tmpOrderGoods = new HashMap<>();
            tmpOrderGoods.put("orderSn", orderSn);
            tmpOrderGoods.put("goodsList", orderGoodsPoList);
            tmpOrderGoods.put("score", orderPo.getIntegralPaymentAmount());
            signData.add(tmpOrderGoods);
            allScore = allScore + orderPo.getIntegralPaymentAmount();
        }
        totalFee.put("goods", goodsAmount);
        totalFee.put("order", orderAmount);
        totalFee.put("signData", signData);
        distributor = stringRedisTemplate.opsForValue().get("appDistributor:" + paySn);

        // 是否分润：1-要分润(给购买者和分享人建立上下级关系)0-不分
//        int type = 0;
//        if (!StringUtils.isEmpty(distributor)) {
//            type = 1;
//        }
//        // 是否有临时上级
//        boolean recommend = false;
//        // 商品购买后绑定上下级关系
//        if (!StringUtils.isEmpty(customerId) && !StringUtils.isEmpty(distributor) && type == 1 && !customerId.equals(distributor)) {
//            Map<String, Long> userRole = purchaseProcessDao.getUserRoleMapByCustomerId(distributor);
//            Long c = userRole.get("c");
//            String pid = purchaseProcessDao.getPidByCid(customerId);
//            if (c == 1 && StringUtils.isEmpty(pid)) {
//                recommend = true;
//            }
//        }
        List feeList = (List) totalFee.get("signData");
        //通联支付（暂时默认）
        Integer payMode = mallService.getPayModeByOrgId(orgId);
        LOGGER.info("app的支付方式========》" + payMode);
        return purchaseProcessNewService.getSign(param, paySn, payMode, feeList, rePay, orgId, allScore, customerId, orderIds, distributor);

//        //查询orderSn,payMode,totalFee, rePay,orderIds,orgId,score,customerId,distributor,type,recommend
//        //orderSn
//        String orderSn;
//        if(param.get("orderSn")==null){
//            throw GlobalException.build("订单号不能为空！");
//        }else {
//            orderSn = param.get("orderSn").toString();
//        }
//        //根据订单号查询
//        AppPayPo appPayPo = mallDao.getAppPayPoByOrderSn(orderSn);
//
//
//        //orderId
//        Long orderId = 1L;
//        List<Long> orderIds = new ArrayList<Long>();
//        orderIds.add(orderId);
//        //orgId
//        String orgId = appPayPo.getOrgId();
//        //customerId
//        String customerId = appPayPo.getCustomerId();
//        param.put("customerId",customerId);
//        //score
//        Integer score = 0;
//        if (appPayPo.getSource() > 0) {
//            score = purchaseProcessDao.getScoreByCustomerId(customerId);
//        }
//        //distributor
//        String distributor = appPayPo.getDistributor();
//        // 是否分润：1-要分润(给购买者和分享人建立上下级关系)0-不分
//        int type = 0;
//        if(!StringUtils.isEmpty(distributor)){
//            type = 1;
//        }
//        //Map<String, Long> totalFee
//        Map<String, Long> totalFee = new HashMap<>();
//        totalFee.put("goods",appPayPo.getGoods());
//        totalFee.put("order",appPayPo.getOrder());
//        if(!StringUtils.isEmpty(appPayPo.getGoodsIds())){
//            String[] goodsIds = appPayPo.getGoodsIds().split(",");
//            if(goodsIds.length==1){
//                String goodsId = goodsIds[0];
//                Map map = new HashMap();
//                map.put("goodsId",goodsId);
//                ShoppingCartGoodsPo goodsPo = mallDao.getShoppingGoodsInfo(map);
//                if (!StringUtils.isEmpty(goodsPo.getBelongId())) {
//                    // 如果为小b商品
//                    totalFee.put("goodsId", goodsPo.getGoodsId());
//                } else if (type==1) {
//                    totalFee.put("goodsId", goodsPo.getGoodsId());
//                }
//            }
//        }
//        // 是否有临时上级
//        boolean recommend = false;
//        // 商品购买后绑定上下级关系
//        if (!StringUtils.isEmpty(customerId) && !StringUtils.isEmpty(distributor) && type == 1 && !customerId.equals(distributor)) {
//            Map<String, Long> userRole = purchaseProcessDao.getUserRoleMapByCustomerId(distributor);
//            Long c = userRole.get("c");
//            String pid = purchaseProcessDao.getPidByCid(customerId);
//            if (c == 1 && StringUtils.isEmpty(pid)) {
//                recommend = true;
//            }
//        }
//        return getSign(param,orderSn,payMode,totalFee, rePay,orderIds,orgId,score,customerId,distributor,type,recommend);
    }

    /**
     * 订单支付回调
     */
    @Override
    public void payCallback(Map<String, Object> param) throws Exception {
        String orderSn = param.get("orderSn").toString();
        String key = "payorder:payorder_" + param.get("orderSn");
        String orderPay = stringRedisTemplate.opsForValue().getAndSet(key, "1");
        stringRedisTemplate.expire(key, 900, TimeUnit.SECONDS);
        if (StringUtils.isEmpty(orderPay)) {
            String typeString = stringRedisTemplate.opsForValue().get("orderType_" + param.get("orderSn"));
            Integer type;
            if (StringUtils.isEmpty(typeString)) {
                if (orderSn.startsWith("I")) {
                    type = 6;
                } else if (orderSn.startsWith("Y")) {
                    type = 4;
                } else {
                    type = purchaseProcessDao.checkOrderTypeByPySn(param);
                }
            } else {
                LOGGER.info("订单回调类型缓存：" + typeString);
                type = Integer.valueOf(typeString);
            }
            switch (type) {
                case 6:
                    //
                    if ("20".equals(param.get("status"))) {
                        integralH5Service.shopCallback(param);
                    }
                    break;
                case 5:
                    //会员
                    if ("20".equals(param.get("status"))) {
                        this.vipCallback(param);
                    }
                    break;
                case 4:
                    //国学娃娃报名
                    stringRedisTemplate.opsForList().rightPush("callbackOrder:enrollPayCallBack", JSON.toJSONString(param));
                    break;
                case 3:
                    //提現
                    // orderSn 查 withdrawid
                    String withDrawId = purchaseProcessDao.getWithDrawIdByOrderSn(param);
                    param.put("withDrawId", withDrawId);
                    this.withdrawCallback(param);
                    break;
                case 2:
                    if ("20".equals(param.get("status"))) {
                        LOGGER.info("订单回调----写入redis队列" + JSON.toJSONString(param));
                        //商品购买回调增加商品的回调队列
                        stringRedisTemplate.opsForList().rightPush("callbackOrder:goodsPayCallBack", JSON.toJSONString(param));
                    }
                    break;
                case 1:
                    // 开通联盟商家和加盟代理
                    if ("20".equals(param.get("status"))) {
                        if (param.containsKey("type") && "5".equals(param.get("type").toString())) {
                            notifyOpen(param);
                            this.joinCallback(param);
                        }
                        if (!param.containsKey("type")) {
                            notifyOpen(param);
                            this.joinCallback(param);
                        }
                    }
                    break;
                default:
                    break;
            }
            String paysKey = payStatusKey + param.get("orderSn");
            stringRedisTemplate.opsForValue().set(paysKey, "1");
            stringRedisTemplate.expire(paysKey, 1200, TimeUnit.SECONDS);
        }
    }

    private void notifyOpen(Map params) {
        String outTradeNo = (String) params.get("orderSn");//商户订单号
        String totalFeeStr = (String) params.get("totalFee");//订单金额
        Integer totalFee = Integer.valueOf(totalFeeStr);
        HashMap<String, Object> salerOrderInfo = mallBoomService.getSalerOrderBySn(outTradeNo);
        if ("1".equals(salerOrderInfo.get("payStatus"))) {
            throw GlobalException.build("该订单已支付完成");
        }
        String orgId = (String) salerOrderInfo.get("orgId");
        String customerId = (String) salerOrderInfo.get("customerId");
        String pid = (String) salerOrderInfo.get("pid");

        //更新用户最后活跃时间
        wxShareDao.setCustomerLastInteraction(customerId);

        Integer payMode = mallService.getPayModeByOrgId(orgId);
        LOGGER.info("开通orgId----》" + orgId);
        LOGGER.info("开通payMode----》" + payMode);
        if (payMode == 2 || payMode == 3) {
            this.signalAgentPay(outTradeNo, orgId);
        }
        Long amount = (Long) salerOrderInfo.get("amount");
        if (totalFee == amount.intValue()) {
            if ("saler".equals(salerOrderInfo.get("orderType").toString())) {
                merchantSalerController.addSaler(pid, customerId, orgId, totalFee);
                merchantSalerService.addSalerNum(orgId);

                /**************************************开通联盟商家自动开通加盟代理***************************************/
                try {
                    Map<String, String> tmpParam = new HashMap<>();
                    tmpParam.put("orgId", orgId);
                    tmpParam.put("customerId", customerId);
                    Integer salerPromoter = mallBoomService.getSalerPromoter(tmpParam);
                    if (null != salerPromoter && 1 == salerPromoter) {
                        Map<String, Object> promoterInfo = mallBoomService.getPromoterInfo(tmpParam);
                        if (null != promoterInfo) {
                            if (!"promoter".equals(promoterInfo.get("customerType")) && !"1".equals(promoterInfo.get("promoterStatus"))) {
                                if (merchantSalerDao.checkPromoter(orgId) > 0) {
                                    Map<String, String> proOrdParam = new HashMap<>();
                                    String proOrderSn = TransactionOrderUtil.TYPE_SHOP + this.getUniquePrimaryKey();
                                    proOrdParam.put("orderSn", proOrderSn);
                                    proOrdParam.put("createTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                                    proOrdParam.put("amount", "0");
                                    proOrdParam.put("pid", "");
                                    proOrdParam.put("orgId", orgId);
                                    proOrdParam.put("customerId", customerId);
                                    proOrdParam.put("payStatus", "1");
                                    proOrdParam.put("orderType", "promoter");
                                    Integer payModeTmp = payMode + 2;
                                    proOrdParam.put("payType", payModeTmp.toString());
                                    mallBoomService.addSalerOrder(proOrdParam);
                                    mallBoomService.savePromoter(customerId);
                                    merchantSalerDao.addPromoterNum(orgId);
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    LOGGER.error(e.getMessage());
                    e.printStackTrace();
                }
                /**************************************开通联盟商家自动开通加盟代理***************************************/

                new Thread(() -> {
                    try {
                        Thread.sleep(1000L);
                        merchantSalerController.getCasUser(customerId);
                    } catch (Exception e) {
                        LOGGER.error("获取小b的cas账号错误", e);
                    }
                }).start();

            }
            if ("promoter".equals(salerOrderInfo.get("orderType").toString())) {
                mallBoomService.savePromoter(customerId);
                merchantSalerService.addPromoterNum(orgId);
            }

//            String pidByCid = purchaseProcessDao.getPidByCid(customerId);
//            Map<String, Long> userRoleMap = purchaseProcessDao.getUserRoleMapByCustomerId(pidByCid);
//            Long c = userRoleMap.get("c");
//            if (c == 1) {
//                // 上级是加盟代理的订单(用于统计数据)
//                purchaseProcessDao.insertPromoterOrder(outTradeNo);
//            }
            merchantSalerController.savePCustomer(customerId, pid, orgId);
//            merchantSalerController.getCasUser(customerId);
        }
    }

    /**
     * 开通vip
     */
    private void vipCallback(Map<String, Object> param) throws Exception {
        if (StringUtils.isEmpty(param.get("orderSn"))) {
            throw GlobalException.build("缺少业务订单编号");
        }
//        Integer count = purchaseProcessDao.countTradeByPaySn(param.get("orderSn").toString());
        Integer count = purchaseProcessDao.getVipOrderPayStatus(param.get("orderSn").toString());
        if (count > 0) {
            LOGGER.warn("该订单已支付完成" + param);
//            throw GlobalException.build("该订单已支付完成");
            return;
        }
        if ("20".equals(param.get("status"))) {
            Map<String, Object> orderParam = new HashMap<>();
            orderParam.put("tradeSn", param.get("txsn"));
            orderParam.put("paymentTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            orderParam.put("orderSn", param.get("orderSn"));
            vipCustomerLogDao.doneOrder(orderParam);

            //获取订单详情
            VipCustomerLogPo vipLogInfo = vipCustomerLogDao.vipLogInfoByOrderSn(param.get("orderSn").toString());
            if (null != vipLogInfo) {
                if (4 == vipLogInfo.getVipType()) {
                    Map<String, Object> iParam = new HashMap<>();
                    iParam.put("id", vipLogInfo.getIntegralVipId());
                    Map<String, Object> integralVipInfo = vipCustomerLogDao.getIntegralVipInfo(iParam);
                    String options = integralVipInfo.get("options").toString();
                    List<Map<String, Object>> optionsList = (List) JSON.parse(options);
                    for (Map<String, Object> op : optionsList) {
                        if (vipLogInfo.getIntegralOptionId() == Long.parseLong(op.get("optionId").toString())) {
                            int goodsCount = Integer.valueOf(op.get("goodsCount").toString());
                            op.put("goodsCount", goodsCount - 1);
                        }
                    }
                    Map<String, Object> tmp = new HashMap<>();
                    tmp.put("options", JSON.toJSONString(optionsList));
                    tmp.put("integralVipId", vipLogInfo.getIntegralVipId());
                    vipCustomerLogDao.saveIntegralGoods(tmp);
                    //积分兑换订单
                    vipCustomerLogDao.addSaleNum(vipLogInfo.getIntegralVipId());
                }
                if (!StringUtils.isEmpty(vipLogInfo.getVipBenefit())) {
                    vipCustomerLogService.openBenefit(vipLogInfo.getVipBenefit(), vipLogInfo.getOrgId(), vipLogInfo.getCustomerId(), vipLogInfo.getPayType());
                }
                Map vipMap = new HashMap();
                vipMap.put("id", vipLogInfo.getVipId());
                VipPo vipPo = vipCustomerLogDao.vipInfo(vipMap);
                if ((vipPo.getGiftsGrowth() != null && vipPo.getGiftsGrowth() > 0) || (vipPo.getGiftsIntegral() != null && vipPo.getGiftsIntegral() > 0) || vipPo.getIsCoupon() == 1) {
                    Integer giftsGrowth = 0;
                    if (vipPo.getGiftsGrowth() != null) {
                        giftsGrowth = vipPo.getGiftsGrowth();
                    }
                    Integer giftsIntegral = 0;
                    if (vipPo.getGiftsIntegral() != null) {
                        giftsIntegral = vipPo.getGiftsIntegral();
                    }
                    //礼包
                    vipCustomerLogService.addGifts(giftsGrowth, giftsIntegral, vipLogInfo.getCustomerId(), 1, vipLogInfo.getOrgId(), "", vipPo.getId().toString());
                }
                String orgId = vipLogInfo.getOrgId();
                Integer orderAmount = vipLogInfo.getAmount();
                Map<String, String> cutPercent = mallBoomService.getOrgCutByOrgId(orgId);
                Integer linkerCut = this.getCutMoney(orderAmount, cutPercent.get("linkerTake"));//联汇抽成
                Integer unionbarleyCut = this.getCutMoney(orderAmount, cutPercent.get("unionbarleyTake"));//大麦抽成
                Integer platformCut = linkerCut + unionbarleyCut;//手续费
                Integer openMoney = vipLogInfo.getAmount() - platformCut;//联盟商家开通费=订单成交金额-手续费

                String RatioCutString = stringRedisTemplate.opsForValue().get("vipRatioCut:" + vipLogInfo.getOrderSn());

                Calendar c = Calendar.getInstance();
                if (StringUtils.isEmpty(RatioCutString)) {
                    //没有服务费的7天结算，否则立即结算
                    c.add(Calendar.DAY_OF_MONTH, 7);
                }
                Date endTime = c.getTime();
                SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String unFreezeTime = sf.format(endTime);
                Map<String, Object> tradeParam = new HashMap<>();
                tradeParam.put("from", vipLogInfo.getCustomerId());
                tradeParam.put("to", orgId);
                tradeParam.put("amount", vipLogInfo.getAmount());
                tradeParam.put("tradeType", TradeTypeConstants.VIP_FEE);//交易类型：21-开通vip
                tradeParam.put("receiveRole", 1);//收款角色：4-大B
                tradeParam.put("payType", 1);//金额类型 1.现金 2.金币
                tradeParam.put("accountType", this.getAccountTypeByFeeTypeAndOrgId(FeeConstants.VIP_FEE, orgId));

                Map<String, Object> map = new HashMap<>();
                map.put("orderName", vipLogInfo.getVipName() + vipLogInfo.getVipEffectiveMonth() + "个月开通");
                map.put("orgId", orgId);
                Integer payMode = mallService.getPayModeByOrgId(orgId);
                map.put("payMode", payMode);
                TradeInfo tradeInfo = BeanMapUtils.mapToBean(tradeParam, TradeInfo.class);
                TradeInfo tradeInfo0 = new TradeInfo();
                tradeInfo0.setAmount(openMoney);
                tradeInfo0.setTo(tradeInfo.getTo());
                purchaseProcessDao.updateOrgAccountFreeze(tradeInfo0);
                Integer balance = purchaseProcessDao.getOrgBalanceByOrgId(orgId);
                map.put("balance", balance);
                map.put("orderSn", vipLogInfo.getOrderSn());
                map.put("tradeInfo", tradeInfo);
                map.put("unFreezeTime", unFreezeTime);
                // 生成业务单号
                String busiSn = this.generateBusiSn(22, vipLogInfo.getCustomerId());
                map.put("busiSn", busiSn);
                map.put("serialNo", param.get("txsn").toString());
                purchaseProcessDao.insertProtectTradeInfo(map);

                //记录联汇抽成
                if (linkerCut > 0) {
                    Map<String, Object> tradeParam1 = new HashMap<>();
                    tradeParam1.put("from", vipLogInfo.getCustomerId());
                    String toLink = purchaseProcessDao.getLinkIdByOrgId(orgId);
                    if (toLink == null) {
                        toLink = "";
                    }
                    tradeParam1.put("to", toLink);
                    tradeParam1.put("amount", linkerCut);
                    tradeParam1.put("tradeType", 9);
                    tradeParam1.put("receiveRole", 0);
                    tradeParam1.put("payType", 1);//金额类型 1.现金 2.金币
                    tradeParam1.put("accountType", this.getAccountTypeByFeeTypeAndOrgId(FeeConstants.VIP_FEE, orgId));

                    Map<String, Object> map1 = new HashMap<>();
                    map1.put("orderName", "平台抽成");
                    map1.put("orgId", orgId);
                    map1.put("payMode", payMode);
                    TradeInfo tradeInfo1 = BeanMapUtils.mapToBean(tradeParam1, TradeInfo.class);
                    Integer balance1 = purchaseProcessDao.getOrgBalanceByOrgId(orgId);
                    map1.put("balance", balance1);
                    map1.put("orderSn", vipLogInfo.getOrderSn());
                    map1.put("tradeInfo", tradeInfo1);
                    map1.put("unFreezeTime", unFreezeTime);
                    // 生成业务单号
                    String busiSn1 = this.generateBusiSn(22, vipLogInfo.getCustomerId());
                    map1.put("busiSn", busiSn1);
                    map1.put("serialNo", param.get("txsn").toString());
                    purchaseProcessDao.insertProtectTradeInfo(map1);
                }
                //记录大麦抽成
                if (unionbarleyCut > 0) {
                    //支付抽成
                    Map<String, Object> tradeParam1 = new HashMap<>();
                    tradeParam1.put("from", vipLogInfo.getCustomerId());
                    tradeParam1.put("to", orgId);
                    tradeParam1.put("amount", unionbarleyCut);
                    tradeParam1.put("tradeType", TradeTypeConstants.PAY_CENTAGE_FEE);
                    tradeParam1.put("receiveRole", 1);
                    tradeParam1.put("payType", 1);//金额类型 1.现金 2.金币
                    tradeParam1.put("accountType", this.getAccountTypeByFeeTypeAndOrgId(FeeConstants.VIP_FEE, orgId));

                    Map<String, Object> map1 = new HashMap<>();
                    map1.put("orderName", "支付抽成");
                    map1.put("orgId", orgId);
                    map1.put("payMode", payMode);
                    TradeInfo tradeInfo1 = BeanMapUtils.mapToBean(tradeParam1, TradeInfo.class);

                    //大麦加余额
                    purchaseProcessDao.updateOrgAccountFreeze(tradeInfo1);
                    Integer balance1 = purchaseProcessDao.getOrgBalanceByOrgId(orgId);
                    map1.put("balance", balance1);
                    map1.put("orderSn", vipLogInfo.getOrderSn());
                    map1.put("tradeInfo", tradeInfo1);
                    map1.put("unFreezeTime", unFreezeTime);
                    // 生成业务单号
                    String busiSn1 = this.generateBusiSn(22, vipLogInfo.getCustomerId());
                    map1.put("busiSn", busiSn1);
                    map1.put("serialNo", param.get("txsn").toString());
                    purchaseProcessDao.insertProtectTradeInfo(map1);
                }
                // 交易手续费
                if (platformCut > 0) {
                    //交易手续费
                    Map<String, Object> tradeParam1 = new HashMap<>();
                    tradeParam1.put("from", orgId);
                    tradeParam1.put("to", "");
                    tradeParam1.put("amount", platformCut);
                    tradeParam1.put("tradeType", TradeTypeConstants.TRADE_SERVER_FEE);
                    tradeParam1.put("receiveRole", -1);
                    tradeParam1.put("payRole", 1);
                    tradeParam1.put("payType", 1);//金额类型 1.现金 2.金币
                    tradeParam1.put("accountType", "");

                    Map<String, Object> map1 = new HashMap<>();
                    map1.put("orderName", vipLogInfo.getVipName() + vipLogInfo.getVipEffectiveMonth() + "个月开通");
                    map1.put("orgId", orgId);
                    map1.put("payMode", payMode);
                    TradeInfo tradeInfo1 = BeanMapUtils.mapToBean(tradeParam1, TradeInfo.class);

                    Integer balance1 = purchaseProcessDao.getOrgBalanceByOrgId(orgId);
                    map1.put("balance", balance1);
                    map1.put("orderSn", vipLogInfo.getOrderSn());
                    map1.put("tradeInfo", tradeInfo1);
                    map1.put("unFreezeTime", unFreezeTime);
                    // 生成业务单号
                    String busiSn1 = this.generateBusiSn(22, vipLogInfo.getCustomerId());
                    map1.put("busiSn", busiSn1);
                    map1.put("serialNo", param.get("txsn").toString());
                    purchaseProcessDao.insertProtectTradeInfo(map1);
                }
                //是否有反润
                if (!StringUtils.isEmpty(RatioCutString)) {
                    Object parse = JSON.parse(RatioCutString);
                    Map RatioMap = (Map) parse;

                    //交易分润（服务费）
                    Map<String, Object> tradeParam4 = new HashMap<>();
                    tradeParam4.put("from", vipLogInfo.getCustomerId());
                    tradeParam4.put("to", RatioMap.get("shareCustomerId"));
                    tradeParam4.put("amount", RatioMap.get("splitAmount"));
                    tradeParam4.put("tradeType", TradeTypeConstants.SERVER_FEE);
                    tradeParam4.put("receiveRole", -1);
                    tradeParam4.put("payRole", 5);
                    tradeParam4.put("receiveRole", 5);
                    tradeParam4.put("payType", 1);//金额类型 1.现金 2.金币
                    tradeParam4.put("accountType", "");

                    Map<String, Object> map4 = new HashMap<>();
                    map4.put("orderName", vipLogInfo.getVipName() + vipLogInfo.getVipEffectiveMonth() + "个月开通");
                    map4.put("orgId", orgId);
                    map4.put("payMode", payMode);
                    TradeInfo tradeInfo4 = BeanMapUtils.mapToBean(tradeParam4, TradeInfo.class);

                    Integer balance4 = purchaseProcessDao.getUserBalanceByCustomerId(RatioMap.get("shareCustomerId").toString());
                    map4.put("balance", balance4);
                    map4.put("orderSn", vipLogInfo.getOrderSn());
                    map4.put("tradeInfo", tradeInfo4);
                    map4.put("unFreezeTime", unFreezeTime);
                    // 生成业务单号
                    String busiSn1 = this.generateBusiSn(22, vipLogInfo.getCustomerId());
                    map4.put("busiSn", busiSn1);
                    map4.put("serialNo", param.get("txsn").toString());
                    purchaseProcessDao.insertProtectTradeInfo(map4);
                    purchaseProcessDao.updateCustomerAccountFreeze(tradeInfo4);
                    stringRedisTemplate.delete("home:customer_info_" + RatioMap.get("shareCustomerId").toString());

                    //反润佣金
                    Map<String, Object> tradeParam5 = new HashMap<>();
                    tradeParam5.put("from", orgId);
                    tradeParam5.put("to", "");
                    tradeParam5.put("amount", RatioMap.get("splitAmount"));
                    tradeParam5.put("tradeType", TradeTypeConstants.REJUVENATE_FEE);
                    tradeParam5.put("receiveRole", -1);
                    tradeParam5.put("payRole", 1);
                    tradeParam5.put("receiveRole", -1);
                    tradeParam5.put("payType", 1);//金额类型 1.现金 2.金币
                    tradeParam5.put("accountType", "");

                    Map<String, Object> map5 = new HashMap<>();
                    map5.put("orderName", vipLogInfo.getVipName() + vipLogInfo.getVipEffectiveMonth() + "个月开通");
                    map5.put("orgId", orgId);
                    map5.put("payMode", payMode);
                    TradeInfo tradeInfo5 = BeanMapUtils.mapToBean(tradeParam5, TradeInfo.class);
                    Integer balance5 = purchaseProcessDao.getOrgBalanceByOrgId(orgId);
                    map5.put("balance", balance5);
                    map5.put("orderSn", vipLogInfo.getOrderSn());
                    map5.put("tradeInfo", tradeInfo5);
                    map5.put("unFreezeTime", unFreezeTime);
                    // 生成业务单号
                    String busiSn5 = this.generateBusiSn(22, vipLogInfo.getCustomerId());
                    map5.put("busiSn", busiSn5);
                    map5.put("serialNo", param.get("txsn").toString());
                    purchaseProcessDao.insertProtectTradeInfo(map5);

                    purchaseProcessDao.insertPromoterOrder(vipLogInfo.getOrderSn(), 3);
                }

                String vipShareCustomerId = stringRedisTemplate.opsForValue().get("vipShareCustomerId:" + vipLogInfo.getOrderSn());
                if (!StringUtils.isEmpty(vipShareCustomerId)) {
                    //异步添加销售线索
                    Map clueMap = new HashMap();
                    clueMap.put("promoterId", vipShareCustomerId);
                    clueMap.put("customerId", vipLogInfo.getCustomerId());
                    clueMap.put("actionType", 13);
                    clueMap.put("relevantId", vipLogInfo.getVipId());
                    clueMap.put("relevantName", vipLogInfo.getVipName());
                    clueMap.put("amount", vipLogInfo.getAmountStr());
                    clueMap.put("orderSn", vipLogInfo.getOrderSn());
                    clueMap.put("type", 2);
                    clueMap.put("orgId", orgId);
                    //增加销售线索
                    promoterClueService.addClue(clueMap);
                }
            }
        }

    }

    /**
     * 开通联盟商家和加盟代理回调
     */
    private void joinCallback(Map<String, Object> param) throws Exception {
        if (StringUtils.isEmpty(param.get("orderSn"))) {
            throw GlobalException.build("缺少业务订单编号");
        }
        if ("20".equals(param.get("status"))) {
            Map<String, Object> orderParam = new HashMap<>();
            orderParam.put("tradeSn", param.get("txsn"));
            orderParam.put("paymentTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
            orderParam.put("orderSn", param.get("orderSn"));
            mallBoomService.doneSalerOrder(orderParam);

            //获取订单详情
            Map<String, Object> orderInfo = mallBoomService.getSalerOrderBysn(param.get("orderSn").toString());
            if (null != orderInfo) {
                String orgId = orderInfo.get("orgId").toString();
                Integer orderAmount = Integer.valueOf(String.valueOf(orderInfo.get("amount")));
                String orderType = orderInfo.get("orderType").toString();//订单类型 saler:加入联盟商家订单，promoter：加盟代理订单
                Map<String, String> cutPercent = mallBoomService.getOrgCutByOrgId(orgId);
                Integer linkerCut = this.getCutMoney(orderAmount, cutPercent.get("linkerTake"));//联汇抽成
                Integer unionbarleyCut = this.getCutMoney(orderAmount, cutPercent.get("unionbarleyTake"));//大麦抽成

                Integer platformCut = linkerCut + unionbarleyCut;//手续费
                Integer openMoney = orderAmount - platformCut;//联盟商家开通费=订单成交金额-手续费

//                String unFreezeTime = null;
                String unFreezeTime = df.format(LocalDateTime.now());

                if ("promoter".equals(orderType)) {
                    /**
                     * 推广员获得反润
                     *   1.加盟代理开通返润=加盟代理开通费X加盟代理开通返润
                     *   2.提现（线下进行）
                     */
                    Integer offlineMoney = 0;
                    String receiveUserOffline = "";
                    if (!StringUtils.isEmpty(orderInfo.get("pid")) && !"".equals(orderInfo.get("pid").toString())) {
                        String agentStatus = mallBoomDao.getAgentCountStatus(orderInfo.get("pid").toString());
                        if ("0".equals(agentStatus)) {
                            offlineMoney = this.getOfflineMoney(orgId, orderAmount);
                            receiveUserOffline = orderInfo.get("pid").toString();
                        }
                    }
                    this.saveOrgMoneyPromoter(orgId, openMoney, offlineMoney, receiveUserOffline, orderInfo, unFreezeTime, param.get("txsn").toString(), linkerCut, unionbarleyCut, platformCut);
                }
                if ("saler".equals(orderType)) {
                    this.saveOrgMoneySaler(orgId, openMoney, orderInfo, unFreezeTime, param.get("txsn").toString(), linkerCut, unionbarleyCut, platformCut);
                }
            }
        }

    }

    /**
     * 1.联盟大麦
     * 联盟商家开通费=订单成交金额-平台费
     * （1）收支类型：收入
     * （2）是否有冻结时间：有
     */
    private void saveOrgMoneySaler(String orgId, Integer money, Map orderInfo, String unFreezeTime, String serialNo, Integer linkerCut, Integer unionbarleyCut, Integer platformCut) throws Exception {
        Map<String, Object> tradeParam = new HashMap<>();
        tradeParam.put("from", orderInfo.get("customerId"));
        tradeParam.put("to", orgId);
        tradeParam.put("amount", money + platformCut);
        tradeParam.put("tradeType", 6);//交易类型：6-开通联盟商家收益
        tradeParam.put("receiveRole", 1);//收款角色：4-大B
        tradeParam.put("payType", 1);//金额类型 1.现金 2.金币
        tradeParam.put("accountType", this.getAccountTypeByFeeTypeAndOrgId(FeeConstants.MERCHANT_FEE, orgId));

        Map<String, Object> map = new HashMap<>();
        map.put("orderName", "联盟商家开通费");
        map.put("orgId", orgId);
        Integer payMode = mallService.getPayModeByOrgId(orgId);
        map.put("payMode", payMode);
        TradeInfo tradeInfo = BeanMapUtils.mapToBean(tradeParam, TradeInfo.class);
        TradeInfo tradeInfo1 = new TradeInfo();
        tradeInfo1.setAmount(money);
        tradeInfo1.setTo(tradeInfo.getTo());
//2020-03-10         purchaseProcessDao.updateOrgAccountBalance(tradeInfo);
        purchaseProcessDao.updateOrgAccountFreeze(tradeInfo1);
        Integer balance = purchaseProcessDao.getOrgBalanceByOrgId(orgId);
        map.put("balance", balance);
        map.put("orderSn", orderInfo.get("orderSn"));
        map.put("tradeInfo", tradeInfo);
        map.put("unFreezeTime", unFreezeTime);
        // 生成业务单号
        String busiSn = this.generateBusiSn((Integer) tradeParam.get("tradeType"), orderInfo.get("customerId").toString());
        map.put("busiSn", busiSn);
        map.put("serialNo", serialNo);
//        purchaseProcessDao.insertTradeInfo(map);
        purchaseProcessDao.insertProtectTradeInfo(map);

        //记录支付抽成(大b)
        this.savePlatformMoney(5, FeeConstants.MERCHANT_FEE, linkerCut, orgId, orderInfo, serialNo, unFreezeTime);
        //记录大麦抽成
        this.saveOrgMoney(20, FeeConstants.MERCHANT_FEE, unionbarleyCut, orgId, orderInfo, serialNo, unFreezeTime);
        // 交易手续费
        this.saveOrgServerMoney(TradeTypeConstants.TRADE_SERVER_FEE, platformCut, orgId, orderInfo, serialNo, unFreezeTime);
    }

    /**
     * 1.联盟大麦
     * 加盟代理开通费=订单成交金额-平台费
     * （1）收支类型：收入
     * （2）是否有冻结时间：有
     */
    private void saveOrgMoneyPromoter(String orgId, Integer money, Integer offlineMoney, String receiveUserOffline, Map orderInfo, String unFreezeTime, String serialNo, Integer linkerCut, Integer unionbarleyCut, Integer platformCut) throws Exception {
        Map<String, Object> tradeParam = new HashMap<>();
        tradeParam.put("from", orderInfo.get("customerId"));
        tradeParam.put("to", orgId);
        //现在改为总价
        tradeParam.put("amount", money + platformCut);
        tradeParam.put("amountOffline", offlineMoney);
        tradeParam.put("receiveUserOffline", receiveUserOffline);
        tradeParam.put("tradeType", 8);//交易类型：8-开通加盟代理收益
        tradeParam.put("receiveRole", 1);//收款角色：4-大B
        tradeParam.put("payType", 1);//金额类型 1.现金 2.金币
        tradeParam.put("accountType", this.getAccountTypeByFeeTypeAndOrgId(FeeConstants.AGENT_FEE, orgId));

        Map<String, Object> map = new HashMap<>();
        map.put("orderName", "加盟代理开通费");
        map.put("orgId", orgId);
        Integer payMode = mallService.getPayModeByOrgId(orgId);
        map.put("payMode", payMode);
        TradeInfo tradeInfo = BeanMapUtils.mapToBean(tradeParam, TradeInfo.class);

//2020-03-10        purchaseProcessDao.updateOrgAccountBalance(tradeInfo);
        TradeInfo tradeInfo1 = new TradeInfo();
        tradeInfo1.setAmount(money);
        tradeInfo1.setTo(tradeInfo.getTo());
        purchaseProcessDao.updateOrgAccountFreeze(tradeInfo1);
        Integer balance = purchaseProcessDao.getOrgBalanceByOrgId(orgId);
        map.put("balance", balance);
        map.put("orderSn", orderInfo.get("orderSn"));
        map.put("tradeInfo", tradeInfo);
        map.put("unFreezeTime", unFreezeTime);
        // 生成业务单号
        String busiSn = this.generateBusiSn((Integer) tradeParam.get("tradeType"), orderInfo.get("customerId").toString());
        map.put("busiSn", busiSn);
        map.put("serialNo", serialNo);
//        purchaseProcessDao.insertTradeInfo(map);
        purchaseProcessDao.insertProtectTradeInfo(map);

        //记录平台抽成
        this.savePlatformMoney(7, FeeConstants.AGENT_FEE, linkerCut, orgId, orderInfo, serialNo, unFreezeTime);
        //记录大麦抽成（支付抽成(大b)）
        this.saveOrgMoney(21, FeeConstants.AGENT_FEE, unionbarleyCut, orgId, orderInfo, serialNo, unFreezeTime);
        // 交易手续费
        this.saveOrgServerMoney(TradeTypeConstants.TRADE_SERVER_FEE, platformCut, orgId, orderInfo, serialNo, unFreezeTime);
    }

    private void savePlatformMoney(Integer tradeType, String accountType, Integer linkerCut, String orgId, Map orderInfo, String serialNo, String unFreezeTime) throws Exception {
        if (linkerCut == 0) {
            return;
        }
        Map<String, Object> tradeParam = new HashMap<>();
        tradeParam.put("from", orderInfo.get("customerId"));
        tradeParam.put("to", purchaseProcessDao.getLinkIdByOrgId(orgId));
        tradeParam.put("amount", linkerCut);
        tradeParam.put("tradeType", 9);
        tradeParam.put("receiveRole", 1);
        tradeParam.put("payType", 1);//金额类型 1.现金 2.金币
        tradeParam.put("accountType", this.getAccountTypeByFeeTypeAndOrgId(accountType, orgId));

        Map<String, Object> map = new HashMap<>();
        map.put("orderName", "加盟代理开通平台抽成");
        map.put("orgId", orgId);
        Integer payMode = mallService.getPayModeByOrgId(orgId);
        map.put("payMode", payMode);
        TradeInfo tradeInfo = BeanMapUtils.mapToBean(tradeParam, TradeInfo.class);

        Integer balance = purchaseProcessDao.getOrgBalanceByOrgId(orgId);
        map.put("balance", balance);
        map.put("orderSn", orderInfo.get("orderSn"));
        map.put("tradeInfo", tradeInfo);
        map.put("unFreezeTime", unFreezeTime);
        // 生成业务单号
        String busiSn = this.generateBusiSn(tradeType, orderInfo.get("customerId").toString());
        map.put("busiSn", busiSn);
        map.put("serialNo", serialNo);
//        purchaseProcessDao.insertTradeInfo(map);
        purchaseProcessDao.insertProtectTradeInfo(map);
    }

    private void saveOrgMoney(Integer tradeType, String accountType, Integer unionbarleyCut, String orgId, Map orderInfo, String serialNo, String unFreezeTime) throws Exception {
        if (unionbarleyCut == 0) {
            return;
        }
        //支付抽成
        Map<String, Object> tradeParam = new HashMap<>();
        tradeParam.put("from", orderInfo.get("customerId"));
        tradeParam.put("to", orgId);
        tradeParam.put("amount", unionbarleyCut);
        tradeParam.put("tradeType", TradeTypeConstants.PAY_CENTAGE_FEE);
        tradeParam.put("receiveRole", 1);
        tradeParam.put("payType", 1);//金额类型 1.现金 2.金币
        tradeParam.put("accountType", this.getAccountTypeByFeeTypeAndOrgId(accountType, orgId));

        Map<String, Object> map = new HashMap<>();
        map.put("orderName", "支付抽成");
        map.put("orgId", orgId);
        Integer payMode = mallService.getPayModeByOrgId(orgId);
        map.put("payMode", payMode);
        TradeInfo tradeInfo = BeanMapUtils.mapToBean(tradeParam, TradeInfo.class);

        //大麦加余额
//2020-03-10         purchaseProcessDao.updateOrgAccountBalance(tradeInfo);
        purchaseProcessDao.updateOrgAccountFreeze(tradeInfo);
        Integer balance = purchaseProcessDao.getOrgBalanceByOrgId(orgId);
        map.put("balance", balance);
        map.put("orderSn", orderInfo.get("orderSn"));
        map.put("tradeInfo", tradeInfo);
        map.put("unFreezeTime", unFreezeTime);
        // 生成业务单号
        String busiSn = this.generateBusiSn(tradeType, orderInfo.get("customerId").toString());
        map.put("busiSn", busiSn);
        map.put("serialNo", serialNo);
//        purchaseProcessDao.insertTradeInfo(map);
        purchaseProcessDao.insertProtectTradeInfo(map);
    }

    private void saveOrgServerMoney(Integer tradeType, Integer platformCut, String orgId, Map orderInfo, String serialNo, String unFreezeTime) throws Exception {
        if (platformCut == 0) {
            return;
        }
        //交易手续费
        Map<String, Object> tradeParam = new HashMap<>();
        tradeParam.put("from", orgId);
        tradeParam.put("to", "");
        tradeParam.put("amount", platformCut);
        tradeParam.put("tradeType", tradeType);
        tradeParam.put("receiveRole", -1);
        tradeParam.put("payRole", 1);
        tradeParam.put("payType", 1);//金额类型 1.现金 2.金币
        tradeParam.put("accountType", "");

        Map<String, Object> map = new HashMap<>();
        map.put("orderName", "开通交易手续费");
        map.put("orgId", orgId);
        Integer payMode = mallService.getPayModeByOrgId(orgId);
        map.put("payMode", payMode);
        TradeInfo tradeInfo = BeanMapUtils.mapToBean(tradeParam, TradeInfo.class);

        Integer balance = purchaseProcessDao.getOrgBalanceByOrgId(orgId);
        map.put("balance", balance);
        map.put("orderSn", orderInfo.get("orderSn"));
        map.put("tradeInfo", tradeInfo);
        map.put("unFreezeTime", unFreezeTime);
        // 生成业务单号
        String busiSn = this.generateBusiSn(tradeType, orderInfo.get("customerId").toString());
        map.put("busiSn", busiSn);
        map.put("serialNo", serialNo);
//        purchaseProcessDao.insertTradeInfo(map);
        purchaseProcessDao.insertProtectTradeInfo(map);
    }

    private Integer getOfflineMoney(String orgId, Integer orderAmount) {
        Map<String, Integer> reverseProfitModel = mallBoomDao.getReverseProfitModel(orgId);
        return this.getCutMoney(orderAmount, reverseProfitModel.get("seniorRebate").toString());//加盟代理开通返润
    }

    /**
     * 推广员获得反润
     * 1.加盟代理开通返润=加盟代理开通费X加盟代理开通返润
     * 2.提现（线下进行）
     */
    private Integer saveSeniorMoney(String orgId, Integer orderAmount, Map orderInfo, String unFreezeTime, String serialNo) throws Exception {
        Map<String, Integer> reverseProfitModel = mallBoomDao.getReverseProfitModel(orgId);
        Integer promoterCut = this.getCutMoney(orderAmount, reverseProfitModel.get("seniorRebate").toString());//加盟代理开通返润
        Map<String, Object> tradeParam = new HashMap<>();
        tradeParam.put("from", orderInfo.get("customerId"));
        tradeParam.put("to", orderInfo.get("pid"));
        tradeParam.put("amount", promoterCut);
        tradeParam.put("tradeType", 13);//交易类型：13-开通加盟代理服务费
        tradeParam.put("receiveRole", 4);//收款角色：4-推广员
        tradeParam.put("payType", 1);//收款角色：4-推广员
        tradeParam.put("accountType", this.getAccountTypeByFeeTypeAndOrgId(FeeConstants.AGENT_FEE, orgId));

        Map<String, Object> map = new HashMap<>();
        map.put("orgId", orgId);
        TradeInfo tradeInfo = BeanMapUtils.mapToBean(tradeParam, TradeInfo.class);
        // todo
        purchaseProcessDao.updateAgentAccountFreeze(tradeInfo);
        Integer balance = purchaseProcessDao.getUserBalanceByCustomerId(orderInfo.get("pid").toString());
        map.put("balance", balance);
        map.put("orderSn", orderInfo.get("orderSn"));
        map.put("tradeInfo", tradeInfo);
        map.put("unFreezeTime", unFreezeTime);
        // 生成业务单号
        String busiSn = this.generateBusiSn((Integer) tradeParam.get("tradeType"), orderInfo.get("customerId").toString());
        map.put("busiSn", busiSn);
        map.put("serialNo", serialNo);
        purchaseProcessDao.insertTradeInfo(map);
        return promoterCut;
    }

    /**
     * 计算反润金额
     *
     * @param sysAmount
     * @param cutPercent
     * @return
     */
    @Override
    public Integer getCutMoney(Integer sysAmount, String cutPercent) {
        double v = sysAmount.doubleValue() * Double.valueOf(cutPercent) / 100;
        return new BigDecimal(v).setScale(0, BigDecimal.ROUND_HALF_EVEN).intValue();
    }

    /**
     * @Description: 提现回调
     * @Param: orderSn：订单号 status：订单状态 txsn：提现交易流水号
     * @Return:
     * @Author: 锋
     * @Date: 2019/10/11 17:54
     * @Version: 1.9.1
     */
    private void withdrawCallback(Map<String, Object> param) throws GlobalException {
        if (StringUtils.isEmpty(param.get("orderSn"))
                || StringUtils.isEmpty(param.get("status"))
                || StringUtils.isEmpty(param.get("txsn"))) {
            throw GlobalException.build("缺少参数");
        }
        String orderSn = param.get("orderSn").toString();
        String status = param.get("status").toString();
        String withDrawId = param.get("withDrawId").toString();
        //更新提现记录状态
        purchaseProcessDao.updateWithdrawStatus(param);
        String withdrawMapStr = stringRedisTemplate.opsForValue().get("withdraw:serviceBill" + withDrawId);
        if ("20".equals(status)) {
            //region 手续费记账
            //缓存中拿手续费记账数据
            if (!StringUtils.isEmpty(withdrawMapStr)) {
                Map<String, Object> withdrawMap = (Map) JSON.parse(withdrawMapStr);
                Map<String, Object> addServiceBillMap = (Map) withdrawMap.get("addServiceBillMap");
                Map<String, Object> withdrawTaskMap = (Map) withdrawMap.get("withdrawTaskPo");
                if (withdrawTaskMap.get("source").toString().equals("2")) {
                    if (Long.valueOf(withdrawTaskMap.get("serviceMoney").toString()) > 0) {
                        // 手续费给大麦 大麦余额加上 这笔手续费
                        merchantWalletDao.addOrgBalance((String) withdrawTaskMap.get("orgId"), Long.valueOf(withdrawTaskMap.get("serviceMoney").toString()));
                        merchantWalletDao.insertWithdrawFeeDetail(addServiceBillMap);
                    }
                } else {
                    if (Long.valueOf(withdrawTaskMap.get("serviceMoney").toString()) > 0) {
                        // 手续费给大麦 大麦余额加上 这笔手续费
                        merchantWalletDao.addOrgBalance((String) withdrawTaskMap.get("orgId"), Long.valueOf(withdrawTaskMap.get("serviceMoney").toString()));
                        //记账
                        merchantWalletDao.addAccountTrade(addServiceBillMap);
                    }
                }
                stringRedisTemplate.delete("withdraw:serviceBill" + withDrawId);
            }
            //endregion
            purchaseProcessDao.updateWithdrawTradeInfo(param);

        } else {
//            String busiNo = TransactionOrderUtil.BUSI_TYPE_WITHDRAWFAIL + System.currentTimeMillis();
            //region 退款
            if (!StringUtils.isEmpty(withdrawMapStr)) {
                try {
                    LOGGER.info("提现失败，准备退款：" + withdrawMapStr);
                    Map<String, Object> withdrawMap = (Map) JSON.parse(withdrawMapStr);
                    Map<String, Object> withdrawTaskMap = (Map) withdrawMap.get("withdrawTaskPo");
                    if (withdrawTaskMap.get("source").toString().equals("1")) {
                        //用户转账需要退款
                        merchantWalletDao.updateWithdrawTransferInfo((String) withdrawTaskMap.get("customerOrderSn"));
                        //服务费转账需要退款
                        merchantWalletDao.updateWithdrawTransferInfo((String) withdrawTaskMap.get("serviceOrderSn"));
                        if (withdrawTaskMap.containsKey("customerOrderSn") && !StringUtils.isEmpty(withdrawTaskMap.get("customerOrderSn"))) {
                            ledgerProcessService.refundTransferAmount((String) withdrawTaskMap.get("orgId"),
                                    (String) withdrawTaskMap.get("customerId"),
                                    (String) withdrawTaskMap.get("customerOrderSn"),
                                    (String) withdrawTaskMap.get("clientType"));
                        }
                        if (withdrawTaskMap.containsKey("serviceOrderSn") && !StringUtils.isEmpty(withdrawTaskMap.get("serviceOrderSn"))) {
                            ledgerProcessService.refundTransferAmount((String) withdrawTaskMap.get("orgId"),
                                    (String) withdrawTaskMap.get("feeCustomerId"),
                                    (String) withdrawTaskMap.get("serviceOrderSn"),
                                    (String) withdrawTaskMap.get("clientType"));
                        }
                        stringRedisTemplate.delete("withdraw:serviceBill" + withDrawId);
                    }
                } catch (Exception ex) {
                    LOGGER.info("提现回调，转账报错：" + ex.toString());
                }
            }
            //endregion
            //获取提现记录
            Map<String, Object> withdrawInfo = purchaseProcessDao.getWithdrawTradeInfo(orderSn);
            withdrawInfo.put("busiNo", withDrawId);
            withdrawInfo.put("orderSn", orderSn);
            //获得当前余额
            Integer payRole = (Integer) withdrawInfo.get("payRole");
            Map<String, Object> wallet = new HashMap<>();
            switch (payRole) {
                case 1:
                    //大麦
                    purchaseProcessDao.updateOrgAccountbalance(withdrawInfo);
                    wallet = purchaseProcessDao.getOrgAccountInfo(withdrawInfo);
                    break;
                case 2:
                    //小B联盟商家
                    purchaseProcessDao.updateXbAccountbalance(withdrawInfo);
                    wallet = purchaseProcessDao.getXbAccountInfo(withdrawInfo);
                    break;
                case 3:
                    //加盟代理
                    purchaseProcessDao.updateCustomerAccountbalance(withdrawInfo);
                    wallet = purchaseProcessDao.getCustomerAccountInfo(withdrawInfo);
                    break;
                case 4:
                    //推广员
                    purchaseProcessDao.updateCustomerAccountbalance(withdrawInfo);
                    wallet = purchaseProcessDao.getCustomerAccountInfo(withdrawInfo);
                    break;
                case 5:
                    //普通用户
                    purchaseProcessDao.updateCustomerAccountbalance(withdrawInfo);
                    wallet = purchaseProcessDao.getCustomerAccountInfo(withdrawInfo);
                    break;
                default:
                    break;
            }
            if (wallet != null) {
                withdrawInfo.put("balance", Long.valueOf(wallet.get("balance").toString()));
            }
            //提现失败 返回提现金额到余额并生成提现失败交易记录
            purchaseProcessDao.insertWithdrawFailTradeInfo(withdrawInfo);

            //修改提现任务表中的任务状态
            withdrawTaskDao.updateWithdrawTaskStatusByCode(withDrawId, 3);
        }
    }

    /**
     * 直接购买生成订单
     */
    private Map<String, Object> insertMerchantOrder(Map<String, Object> map, OrderAddressDto orderAddressDto, List<Long> orderIds, String orgId) throws GlobalException {
        //拼装订单商品留言参数
        if (null != map.get("goodsRemarkList")) {
            List<Map<String, Object>> goodsRemarkList = (List) map.get("goodsRemarkList");
            if (goodsRemarkList.size() > 0 && null != goodsRemarkList.get(0).get("goodsRemark")) {
                List<Map<String, Object>> goodsRemark = (List) goodsRemarkList.get(0).get("goodsRemark");
                if (null != goodsRemark && goodsRemark.size() > 0) {
                    map.put("goodsRemark", JSON.toJSONString(goodsRemark));
                }
            }
        }
        Integer goodsNum = (Integer) map.get("goodsNum");
        String orderSn = (String) map.get("orderSn");
        String paySn = (String) map.get("paySn");
        String skuId = (String) map.get("skuId");
        String couponId = (String) map.get("couponId");
        String consumptionId = (String) map.get("consumptionId");
        CouponCustomerInfo couponCustomerInfo = (CouponCustomerInfo) map.get("couponCustomerInfo");
        if (null == goodsNum || goodsNum == 0) {
            throw GlobalException.build("参数错误(error:goodsNum)");
        }
        //创作奖励作者/主持人的用户Id
        String author = (String) map.get("author");
        //供货价
        Long mallsAmount = 0L;

//        ShoppingCartGoodsPo goodsPo = mallDao.getShoppingGoodsInfo(map);
        ShoppingCartGoodsPo goodsPo = goodsService.getGoodsSkuInfo(map);
        if (goodsPo == null || (!StringUtils.isEmpty(goodsPo.getSkuId()) && StringUtils.isEmpty(skuId))) {
            throw GlobalException.build("商品失效，请重新下单");
        }
        if (goodsPo.getIsDelete() == 1 || goodsPo.getGoodsStatus() != 1) {
            throw GlobalException.build("商品不存在或已下架");
        }
        Integer isSeckill = goodsPo.getIsSeckill();
        if (isSeckill == 1) {
            //如果是“秒杀”，判断秒杀条件
            String goodsId = map.get("goodsId").toString();
            String customerId = map.get("customerId").toString();
            mallService.killLimit(goodsId, customerId);
        }
        //判断会员价
        if (map.containsKey("isVip") && (boolean) map.get("isVip") && null != goodsPo.getMemberAmountCent() && goodsPo.getMemberAmountCent() > 0) {
            goodsPo.setAmountCent(goodsPo.getMemberAmountCent());
        }
        goodsPo.setBuyCount(goodsNum);
        Integer quota = maiBaoLaService.quota(goodsPo.getGoodsId().toString(), (String) map.get("customerId"));
        if (quota == -3) {
            throw GlobalException.build("您不满足购买条件");
        }
        if (goodsNum > quota && quota != -1) {
            throw GlobalException.build(goodsPo.getGoodsName() + "商品超过了限购上限");
        }

        Integer goodsType = goodsPo.getGoodsType();
        // 是否为知识付费的商品
        boolean isKnowledge = false;
        if (goodsType == 3 || goodsType == 4) {
            isKnowledge = true;
        }
        map.put("isKnowledge", isKnowledge);
        Integer isVirtual = goodsPo.getIsVirtual();
        map.put("isVirtual", isVirtual);
        if (orderAddressDto == null && !isKnowledge && isVirtual != 1) {
            //知识付费、虚拟商品不需要收货地址
            throw GlobalException.build("地址不存在或用户与地址不匹配");
        }
        if (!isKnowledge && goodsPo.getGoodsCount() < goodsNum) {
            throw GlobalException.build("商品库存不足");
        }

        if (orderAddressDto == null) {
            orderAddressDto = new OrderAddressDto();
        }
        if (!isKnowledge && isVirtual != 1) {
            //运费模板
            Map<String, Object> goodsShippingFee = getGoodsShippingFee(orderAddressDto.getAddressId().intValue(), goodsPo.getGoodsId().intValue(), goodsPo.getBuyCount());
            if ((Boolean) goodsShippingFee.get("sta")) {
                goodsPo.setGoodsFreightCent((Long) goodsShippingFee.get("fee"));
            } else {
                throw GlobalException.build(goodsShippingFee.get("tip").toString());
            }
            if (!StringUtils.isEmpty(goodsPo.getMallsGoodsId())) {
                if (goodsPo.getSkuId() == null) {
                    mallsAmount = goodsPo.getMallsAmount();
                } else {
                    mallsAmount = goodsPo.getSkuMallsAmount();
                }
            }
        }
        // 商品总价
        long goodsAmountCent = goodsPo.getAmountCent() * goodsNum;
        map.put("goodsAmountCent", goodsAmountCent);

        // 订单总价
        long orderAmountCent = goodsAmountCent + goodsPo.getGoodsFreightCent();
        // goodsFreightCent areaName cityName provinceName addressInfo phone realName
        map.put("goods", goodsPo);
        map.put("address", orderAddressDto);
        String belongId = goodsPo.getBelongId();
        if (!StringUtils.isEmpty(belongId) || (map.containsKey("type") && (int) map.get("type") == 1)) {
            map.put("orderRebate", "1");
        } else {
            map.put("orderRebate", "0");
        }
        if (isKnowledge) {
            map.put("orderGoodsType", 2);
        } else {
            map.put("orderGoodsType", 1);
        }

        //优惠总金额金额
        int couponAmount = 0;
        long couponTotalAmount = goodsAmountCent;
        long couponReduceAmount = goodsAmountCent;
        //优惠券
        if (!StringUtils.isEmpty(couponId)) {
            //获取优惠券详情
            CouponGoodsPo couponGoodsPo = purchaseProcessDao.getCouponGoods(couponId);
            if (couponGoodsPo.getGoodsType() == 0 ||
                    (couponGoodsPo.getGoodsType() == 1 && couponGoodsPo.getGoodsIds().contains(goodsPo.getGoodsId().toString())) ||
                    (couponGoodsPo.getGoodsType() == 2 && !couponGoodsPo.getGoodsIds().contains(goodsPo.getGoodsId().toString()))
            ) {
                //商品是否符合该优惠券
                Map<String, Object> param = new HashMap<>();
                param.put("couponId", couponId);
                Map<String, Object> couponInfo = new HashMap<>();
                try {
                    couponInfo = couponH5Service.getCouponGoodsData(param, couponCustomerInfo);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw GlobalException.build("优惠券不存在或已过期");
                }
                Integer type = (Integer) couponInfo.get("type");
                if (type == 0) {
                    //满减金额
                    Integer minUsePrice = (Integer) couponInfo.get("minUsePrice");
                    Integer discountPrice = (Integer) couponInfo.get("discountPrice");
                    couponReduceAmount = h5IsLossGoodsService.reduceAmount(couponTotalAmount, minUsePrice, discountPrice);
                } else if (type == 1) {
                    //折扣
                    Integer maxDiscountPrice = (Integer) couponInfo.get("maxDiscountPrice");
                    Integer discountNum = (Integer) couponInfo.get("discountNum");
                    couponReduceAmount = h5IsLossGoodsService.reduceAmountD(couponTotalAmount, maxDiscountPrice, discountNum);
                }
            }
            map.put("couponId", couponId);
            map.put("consumptionId", consumptionId);
        }
        couponAmount = (int) couponTotalAmount - (int) couponReduceAmount;

        map.put("orderTotalPriceCent", orderAmountCent);
        map.put("couponAmount", couponAmount);
        // region 金币抵扣逻辑
        String scoreStr = "0";
        if (!StringUtils.isEmpty(map.get("score"))) {
            scoreStr = map.get("score").toString();
        }
        Integer score = 0;
        if ("1".equals(scoreStr)) {
            score = purchaseProcessDao.getScoreByCustomerId(map.get("customerId").toString());
            int i = (int) (orderAmountCent - couponAmount);
            if (score > i) {
                score = i;
            }
            purchaseProcessDao.updateScoreByCustomerId((long) score, (String) map.get("customerId"));
        }
        map.put("integralPaymentAmount", score);
        map.put("orderAmountCent", orderAmountCent - score - couponAmount);
        //事务管理
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        TransactionStatus status = txManager.getTransaction(def);

        if (!isKnowledge) {
            if (!StringUtils.isEmpty(goodsPo.getOverTime())) {
                SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date overTime = null;
                try {
                    overTime = fmt.parse(goodsPo.getOverTime());
                } catch (Exception e) {
                    throw GlobalException.build("商品库存不足");
                }
                Date nowTime = new Date();
                if (overTime != null && overTime.before(nowTime)) {
                    throw GlobalException.build("商品库存不足");
                }
            }
            int updateCount = saveMallsGoodsCount(goodsPo.getGoodsId(), skuId, goodsNum, goodsPo.getMallsGoodsId(), goodsPo.getMallsSkuId());
            if (updateCount == 0) {
                throw GlobalException.build("商品库存不足");
            }
        }
        map.put("belongId", StringUtils.isEmpty(belongId) ? orgId : belongId);
        if (StringUtils.isEmpty(map.get("storeId"))) {
            map.put("storeId", map.get("belongId"));
        }
        purchaseProcessDao.insertOrderByMap(map);
        Long orderId = Long.valueOf(map.get("orderId").toString());
        orderIds.add(orderId);
        // amountCent goodsCover goodsName skuKey skuValue
        purchaseProcessDao.insertOrderGoodsByMap(map);
        if (!StringUtils.isEmpty(consumptionId) && !StringUtils.isEmpty(couponId)) {
            //使用优惠券
            couponH5Service.useConsumption(consumptionId, (int) (orderAmountCent - couponAmount), orderSn, goodsNum, couponAmount, 0, couponCustomerInfo);
        }
        if (score > 0) {
            //记录金币变动记录
            Map<String, Object> scoreLog = new HashMap<>();
            scoreLog.put("customerId", map.get("customerId"));
            scoreLog.put("score", score);
            scoreLog.put("type", 0);
            scoreLog.put("orderSn", orderSn);
            scoreLog.put("recId", map.get("recId"));
            purchaseProcessDao.addScoreLog(scoreLog);
        }
        if (null != goodsPo.getMallsGoodsId()) {
            String purchaseOrderSn = TransactionOrderUtil.TYPE_SHOP + TransactionOrderUtil.getPrimaryKey();
            map.put("mallsGoodsId", goodsPo.getMallsGoodsId());
            map.put("recId", map.get("recId"));
            map.put("purchaseOrderSn", purchaseOrderSn);
            map.put("orderSn", orderSn);
            map.put("mallsAmount", mallsAmount == null ? 0 : mallsAmount);
            Map mallsGoodsInfo = goodsService.getGoodsInfo(goodsPo.getMallsGoodsId().toString());
            map.put("goodsName", mallsGoodsInfo.get("goodsName"));
            map.put("goodsNum", goodsNum);
            map.put("goodsImage", mallsGoodsInfo.get("goodsCover"));
            map.put("shippingFee", goodsPo.getGoodsFreightCent());
            purchaseProcessDao.addPurchaseOrder(map);
        }
        txManager.commit(status);
        map.put("goodsId", goodsPo.getGoodsId());
        // 赠品异步调用
        this.exercise(map);

//        List<Map<String, Object>> recId = purchaseProcessDao.getRecIdByOrderSn(paySn);
//        // 赠品
//        this.exercise(recId.get(0));
        // 添加记录
        map.put("objectId", map.get("orderSn"));
        mallService.addToDealData(map, 3);
        Map<String, Object> fee = new HashMap<>();
        fee.put("goods", goodsAmountCent);
        fee.put("order", orderAmountCent);
//        if (!StringUtils.isEmpty(goodsPo.getBelongId())  || "1".equals(goodsPo.getPromotion())) {
//            // 如果为小b商品
//            map.put("type",1);
//        }
        fee.put("goodsId", goodsPo.getGoodsId());
        List<Map<String, Object>> signData = new ArrayList<>();
        Map<String, Object> tmpOrderGoods = new HashMap<>();
        List<MerchantOrderGoodsPo> orderGoodsPoList = new ArrayList<>();
        MerchantOrderGoodsPo orderGoodsPo = new MerchantOrderGoodsPo();
        orderGoodsPo.setIsVirtual(isVirtual);
        orderGoodsPo.setCouponAmount("" + couponAmount);
        orderGoodsPo.setPaymentPoints(score);
        orderGoodsPo.setAmountCent(goodsPo.getAmountCent());
        orderGoodsPo.setCustomerId((String) map.get("customerId"));
        orderGoodsPo.setBuyCount(goodsNum);
        orderGoodsPo.setGoodsId(goodsPo.getGoodsId());
        orderGoodsPo.setGoodsName(goodsPo.getGoodsName());
        orderGoodsPo.setShippingFee(goodsPo.getGoodsFreightCent().intValue());
        orderGoodsPo.setSalerId((String) map.get("distributor"));
        orderGoodsPo.setGoodsType(goodsPo.getGoodsType());
        orderGoodsPo.setRecId(Long.valueOf(map.get("recId").toString()));
        orderGoodsPo.setSkuId(goodsPo.getSkuId());
        orderGoodsPo.setAuthor(author);
        orderGoodsPoList.add(orderGoodsPo);
        tmpOrderGoods.put("orderSn", orderSn);
        tmpOrderGoods.put("goodsList", orderGoodsPoList);
        tmpOrderGoods.put("score", score);
        signData.add(tmpOrderGoods);
        fee.put("signData", signData);

        //是否是推广商品
        if ("1".equals(goodsPo.getPromotion())) {
            fee.put("type", 1);
        } else {
            fee.put("type", 0);
        }
        fee.put("score", score);
        LOGGER.info("insertMerchantOrder ------ start 处理业务逻辑完毕返回");
        return fee;
    }

    /**
     * 购物车下单生成订单
     */
    private Map<String, Object> insertMerchantOrderByShoppingCart(Map<String, Object> map, OrderAddressDto orderAddressDto, List<Long> orderIds, String orgId, List<Map> couponMapList) throws GlobalException {

        List<Map<String, Object>> orderList = (List) map.get("orderList");
        CouponCustomerInfo couponCustomerInfo = (CouponCustomerInfo) map.get("couponCustomerInfo");
        List<Map<String, Object>> signData = new ArrayList<>();
        Long totalFee = 0L;
        Long goodsFee = 0L;
        String customerId = (String) map.get("customerId");
        String paySn = (String) map.get("paySn");
        String orderSn = "";
        int allGoodsNum = 0;
        int type = 0;

        int score = 0;
        int allScore = 0;
        long allCartFee = 0L;
        int allCouponAmount = 0;
        String scoreStr = "0";
        if (!StringUtils.isEmpty(map.get("score"))) {
            scoreStr = map.get("score").toString();
        }
        List<Map<String, Object>> goodsScoreList = new ArrayList<>();
        List<Map<String, Object>> goodsCouponList = new ArrayList<>();
        if ("1".equals(scoreStr) || couponMapList.size() > 0) {
            List<Map<String, Object>> goodsAmountList = new ArrayList<>();
            //计算此次下单总金额
            List<String> cartIds = new ArrayList<>();
            for (Map<String, Object> olTmp : orderList) {
                String shoppingCartIds = (String) olTmp.get("shoppingCartIds");
                String[] split = shoppingCartIds.split(",");
                Collections.addAll(cartIds, split);
            }
            Map<String, Object> cartMap = new HashMap<>();
            cartMap.put("shoppingCartIds", cartIds);
            List<ShoppingCartPo> cartPos = mallDao.getShoppingCartByIds(cartMap);
            for (ShoppingCartPo cp : cartPos) {
                List<ShoppingCartGoodsPo> goodsList = cp.getGoodsList();
                for (ShoppingCartGoodsPo gp : goodsList) {
                    if (map.containsKey("isVip") && (boolean) map.get("isVip") && null != gp.getMemberAmountCent() && gp.getMemberAmountCent() > 0) {
                        gp.setAmountCent(gp.getMemberAmountCent());
                    }
                    //运费模板
                    Map<String, Object> goodsShippingFee = getGoodsShippingFee(orderAddressDto.getAddressId().intValue(), gp.getGoodsId().intValue(), gp.getBuyCount());
                    if ((Boolean) goodsShippingFee.get("sta")) {
                        gp.setGoodsFreightCent((Long) goodsShippingFee.get("fee"));
                    } else {
                        throw GlobalException.build(goodsShippingFee.get("tip").toString());
                    }
                    allCartFee = allCartFee + gp.getAmountCent() * gp.getBuyCount() + gp.getGoodsFreightCent();
                    Map<String, Object> goodsAmountMap = new HashMap<>();
                    String tempKey = gp.getGoodsId().toString();
                    if (!StringUtils.isEmpty(gp.getSkuId())) {
                        tempKey = gp.getGoodsId().toString() + gp.getSkuId().toString();
                    }
                    goodsAmountMap.put("goodsPrice", gp.getAmountCent() * gp.getBuyCount() + gp.getGoodsFreightCent());
                    goodsAmountMap.put("goodsSelfPrice", gp.getAmountCent() * gp.getBuyCount());
                    goodsAmountMap.put("couponAmount", 0);
                    goodsAmountMap.put("goodsSku", tempKey);
                    goodsAmountMap.put("goodsId", gp.getGoodsId().toString());
                    goodsAmountList.add(goodsAmountMap);
                }
            }
            if (couponMapList.size() > 0) {
                for (Map couponMap : couponMapList) {
                    //优惠总金额金额
                    int couponAmount = 0;
                    long couponTotalAmount = 0;
                    long couponReduceAmount = 0;
                    String couponId = "";
                    String consumptionId = "";
                    Integer couponGoodsType = -1;
                    String couponGoodsIds = "";
                    Integer couponType = -1;
                    Integer minUsePrice = -1;
                    Integer discountPrice = -1;
                    Integer maxDiscountPrice = -1;
                    Integer discountNum = -1;
                    couponId = couponMap.get("couponId").toString();
                    consumptionId = couponMap.get("consumptionId").toString();
                    //获取优惠券详情
                    CouponGoodsPo couponGoodsPo = purchaseProcessDao.getCouponGoods(couponId);
                    couponGoodsType = couponGoodsPo.getGoodsType();
                    couponGoodsIds = couponGoodsPo.getGoodsIds();
                    //商品是否符合该优惠券
                    Map<String, Object> param = new HashMap<>();
                    param.put("couponId", couponId);
                    Map<String, Object> couponInfo = new HashMap<>();
                    try {
                        couponInfo = couponH5Service.getCouponGoodsData(param, couponCustomerInfo);
                    } catch (Exception e) {
                        e.printStackTrace();
                        throw GlobalException.build("优惠券不存在或已过期");
                    }
                    couponType = (Integer) couponInfo.get("type");
                    if (couponType == 0) {
                        //满减金额
                        minUsePrice = (Integer) couponInfo.get("minUsePrice");
                        discountPrice = (Integer) couponInfo.get("discountPrice");
                    } else if (couponType == 1) {
                        //折扣
                        maxDiscountPrice = (Integer) couponInfo.get("maxDiscountPrice");
                        discountNum = (Integer) couponInfo.get("discountNum");
                    }
                    List<String> goodsIds = new ArrayList<>();
                    for (ShoppingCartPo cp : cartPos) {
                        List<ShoppingCartGoodsPo> goodsList = cp.getGoodsList();
                        for (ShoppingCartGoodsPo gp : goodsList) {
                            if (couponMap.get("shoppingCartIds").toString().contains(gp.getShoppingCartId().toString())) {
                                if (couponGoodsType == 0 || (couponGoodsType == 1 && couponGoodsIds.contains(gp.getGoodsId().toString()))
                                        || (couponGoodsType == 2 && !couponGoodsIds.contains(gp.getGoodsId().toString()))) {
                                    couponTotalAmount += gp.getAmountCent() * gp.getBuyCount();
                                    goodsIds.add(gp.getGoodsId().toString());
                                }
                            }
                        }
                    }
                    //商品是否符合该优惠券（并计算优惠金额）
                    if (couponType == 0) {
                        //满减金额
                        couponReduceAmount = h5IsLossGoodsService.reduceAmount(couponTotalAmount, minUsePrice, discountPrice);
                    } else if (couponType == 1) {
                        //折扣
                        couponReduceAmount = h5IsLossGoodsService.reduceAmountD(couponTotalAmount, maxDiscountPrice, discountNum);
                    }
                    couponAmount = (int) couponTotalAmount - (int) couponReduceAmount;
                    allCouponAmount = allCouponAmount + couponAmount;
                    couponMap.put("couponAmount", couponAmount);
                    couponMap.put("couponTotalAmount", couponTotalAmount);
                    couponMap.put("goodsIds", goodsIds);
                }
            }


            if ((allCartFee - allCouponAmount) < 0) {
                throw GlobalException.build("系统繁忙，请稍后再试(ERROR:CART)");
            }
            if (allCouponAmount > 0) {
                for (Map couponMap : couponMapList) {
                    int couponTotalAmount = 0;
                    int couponAmount = 0;
                    if (!StringUtils.isEmpty(couponMap.get("couponAmount"))) {
                        couponAmount = Integer.valueOf(couponMap.get("couponAmount").toString());

                    }
                    if (!StringUtils.isEmpty(couponMap.get("couponTotalAmount"))) {
                        couponTotalAmount = Integer.valueOf(couponMap.get("couponTotalAmount").toString());

                    }
                    int couponAmountTemp = couponAmount;
                    String couponId = couponMap.get("couponId").toString();
                    String consumptionId = couponMap.get("consumptionId").toString();
                    List<String> goodsIds = (List<String>) couponMap.get("goodsIds");
                    int size = goodsAmountList.size();
                    for (int i = 0; i < size; i++) {
                        Map<String, Object> goodsAmount = goodsAmountList.get(i);
                        String goodsId = goodsAmount.get("goodsId").toString();
                        if (goodsIds.contains(goodsId)) {
                            //除运费
                            long goodsPrice = Long.valueOf(goodsAmount.get("goodsSelfPrice").toString());
                            double v = couponAmount * Math.round(goodsPrice * 10000 / couponTotalAmount) / 10000.0;
                            int goodsCouponAmount = new BigDecimal(v).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();

                            //商品价格占比重太小，分不到优惠份额
                            if (goodsCouponAmount == 0) {
                                //商品价格小于剩余优惠时把商品全部抵扣
                                if (goodsPrice < couponAmountTemp) {
                                    goodsCouponAmount = (int) goodsPrice;
                                } else {
                                    goodsCouponAmount = couponAmountTemp;
                                }
                            } else {
                                if (couponAmountTemp < goodsCouponAmount) {
                                    goodsCouponAmount = couponAmountTemp;
                                }
                            }
                            if ((i + 1) == size) {
                                goodsCouponAmount = couponAmountTemp;
                            }
                            Map<String, Object> goodsCouponMap = new HashMap<>();
                            goodsCouponMap.put("goodsSku", goodsAmount.get("goodsSku"));
                            goodsCouponMap.put("couponAmount", goodsCouponAmount);
                            goodsCouponMap.put("couponId", couponId);
                            goodsCouponMap.put("consumptionId", consumptionId);
                            goodsCouponList.add(goodsCouponMap);
                            goodsAmount.put("couponAmount", goodsCouponAmount);
                            goodsAmount.put("couponId", couponId);
                            goodsAmount.put("consumptionId", consumptionId);
                            couponAmountTemp = couponAmountTemp - goodsCouponAmount;
                        }
                    }

                }
            }


            if ("1".equals(scoreStr)) {
                //计算金币
                score = purchaseProcessDao.getScoreByCustomerId(map.get("customerId").toString());
                //若积分大于订单总金额，使用订单总金额的积分做运算
                if (score > (allCartFee - allCouponAmount)) {
                    score = (int) (allCartFee - allCouponAmount);
                }
                int scoreTemp = score;
                int size = goodsAmountList.size();
                for (int i = 0; i < size; i++) {
                    Map<String, Object> goodsAmount = goodsAmountList.get(i);
                    long goodsPrice = Long.valueOf(goodsAmount.get("goodsPrice").toString());
                    int goodsCouponAmount = Integer.valueOf(goodsAmount.get("couponAmount").toString());
                    double v = score * Math.round((goodsPrice - goodsCouponAmount) * 10000 / (allCartFee - allCouponAmount)) / 10000.0;
                    int goodsScore = new BigDecimal(v).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();

                    //商品价格占比重太小，分不到金币份额
                    if (goodsScore == 0) {
                        //商品价格小于剩余金币时把商品全部抵扣
                        if ((goodsPrice - goodsCouponAmount) < scoreTemp) {
                            goodsScore = (int) (goodsPrice - goodsCouponAmount);
                        } else {
                            goodsScore = scoreTemp;
                        }
                    } else {
                        if (scoreTemp < goodsScore) {
                            goodsScore = scoreTemp;
                        }
                    }
                    if ((i + 1) == size) {
                        goodsScore = scoreTemp;
                    }
                    Map<String, Object> goodsScoreMap = new HashMap<>();
                    goodsScoreMap.put("goodsSku", goodsAmount.get("goodsSku"));
                    goodsScoreMap.put("goodsScore", goodsScore);
                    goodsScoreList.add(goodsScoreMap);
                    scoreTemp = scoreTemp - goodsScore;
                }

            }
        }

        for (Map<String, Object> ol : orderList) {
            String remark = (String) ol.get("remark");
            String shoppingCartIds = (String) ol.get("shoppingCartIds");
            String[] split = shoppingCartIds.split(",");
            List<String> list = Arrays.asList(split);
            map.put("shoppingCartIds", list);
            List<String> merchantIds = mallDao.getShoppingCartMerchantId(map);
            if (merchantIds.size() > 1) {
                throw GlobalException.build("购物车参数错误");
            }
            String merchantId = merchantIds.get(0);
            //生成每个商户的订单号
            orderSn = TransactionOrderUtil.TYPE_SHOP + this.getUniquePrimaryKey();
            map.put("orderSn", orderSn);

            map.put("merchantId", merchantId);
            List<ShoppingCartPo> shoppingCartPos = mallDao.getShoppingCartByIds(map);

            for (ShoppingCartPo cartPo : shoppingCartPos) {
                // 按供货商分订单
                List<ShoppingCartGoodsPo> tempGoodsList = cartPo.getGoodsList();
                Map<String, List<ShoppingCartGoodsPo>> ghList =
                        tempGoodsList.stream().collect(Collectors.groupingBy(ShoppingCartGoodsPo::getMallsBelongId));

                for (String key : ghList.keySet()) {
                    List<ShoppingCartGoodsPo> ghGoodsList = ghList.get(key);
                    //生成每个商户下供货商的订单号
                    orderSn = TransactionOrderUtil.TYPE_SHOP + TransactionOrderUtil.getPrimaryKey();
                    map.put("orderSn", orderSn);
                    //购物车按商户分类，不同商户生成不同订单记录，支付订单号相同
                    long goodAmount = 0L;
                    Long orderAmount = 0L;
                    Long goodsFreight = 0L;
                    Integer goodsBuyNum = 0;
                    List<MerchantOrderGoodsPo> orderGoodsPoList = new ArrayList<>();
                    String distributor = "";
                    String author = "";
                    String belongId = "";
                    int integralPaymentAmount = 0;//订单积分
                    int couponOrderAmount = 0;//订单优惠
                    String consumptionId = "";
                    String couponId = "";
                    for (ShoppingCartGoodsPo goodsPo : ghGoodsList) {
                        belongId = goodsPo.getBelongId();
                        //判断会员价
                        if (map.containsKey("isVip") && (boolean) map.get("isVip") && null != goodsPo.getMemberAmountCent() && goodsPo.getMemberAmountCent() > 0) {
                            goodsPo.setAmountCent(goodsPo.getMemberAmountCent());
                        }
                        if ("1".equals(goodsPo.getPromotion())) {
                            type = 1;
                        }
                        MerchantOrderGoodsPo orderGoodsPo = new MerchantOrderGoodsPo();
                        if (goodsPo.getIsDelete() == 1 || goodsPo.getGoodsStatus() != 1) {
                            throw GlobalException.build(goodsPo.getGoodsName() + "不存在或已下架");
                        }
                        if (goodsPo.getGoodsCount() < goodsPo.getBuyCount()) {
                            throw GlobalException.build(goodsPo.getGoodsName() + "库存不足");
                        }
                        if (!StringUtils.isEmpty(goodsPo.getOverTime())) {
                            SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            Date overTime = null;
                            try {
                                overTime = fmt.parse(goodsPo.getOverTime());
                            } catch (Exception e) {
                                throw GlobalException.build("商品库存不足");
                            }
                            Date nowTime = new Date();
                            if (overTime != null && overTime.before(nowTime)) {
                                throw GlobalException.build("商品库存不足");
                            }
                        }
                        Integer quota = maiBaoLaService.quota(goodsPo.getGoodsId().toString(), customerId);
                        if (quota == -3) {
                            throw GlobalException.build("您不满足购买条件");
                        }
                        if (goodsPo.getBuyCount() > quota && quota != -1) {
                            throw GlobalException.build(goodsPo.getGoodsName() + "商品超过了限购上限");
                        }
                        Integer isSeckill = goodsPo.getIsSeckill();
                        if (isSeckill == 1) {
                            //如果是“秒杀”，判断秒杀条件
                            String goodsId = goodsPo.getGoodsId().toString();
                            try {
                                Integer seckillStatus = mallService.killLimit(goodsId, customerId);
                                goodsPo.setSeckillStatus(seckillStatus);
                            } catch (Exception e) {
                                throw GlobalException.build("有商品无法销售请重新选择");
                            }
                        }

                        Integer updateCount;
                        Long mallsAmount = 0L;
                        goodsBuyNum = goodsBuyNum + goodsPo.getBuyCount();

                        if (goodsPo.getSkuId() == null) {
                            updateCount = saveMallsGoodsCount(goodsPo.getGoodsId(), null, goodsPo.getBuyCount(), goodsPo.getMallsGoodsId(), goodsPo.getMallsSkuId());
                        } else {
                            updateCount = saveMallsGoodsCount(goodsPo.getGoodsId(), goodsPo.getSkuId().toString(), goodsPo.getBuyCount(), goodsPo.getMallsGoodsId(), goodsPo.getMallsSkuId());
                        }

                        if (!StringUtils.isEmpty(goodsPo.getMallsGoodsId())) {
                            if (goodsPo.getSkuId() == null) {
                                mallsAmount = goodsPo.getMallsAmount();
                            } else {
                                mallsAmount = goodsPo.getSkuMallsAmount();
                            }
                        }
                        if (updateCount == 0) {
                            // 更新库存失败
                            throw GlobalException.build(goodsPo.getGoodsName() + "库存不足");
                        } else {
                            goodAmount += goodsPo.getBuyCount() * goodsPo.getAmountCent();
                            orderAmount += goodsPo.getBuyCount() * goodsPo.getAmountCent();

                            goodsPo.setGoodsFreightCent(0L);
                            //运费模板
                            Map<String, Object> goodsShippingFee = getGoodsShippingFee(orderAddressDto.getAddressId().intValue(), goodsPo.getGoodsId().intValue(), goodsPo.getBuyCount());
                            if ((Boolean) goodsShippingFee.get("sta")) {
                                goodsPo.setGoodsFreightCent((Long) goodsShippingFee.get("fee"));
                            } else {
                                throw GlobalException.build(goodsShippingFee.get("tip").toString());
                            }
                            // 取运费之和
                            goodsFreight += goodsPo.getGoodsFreightCent();

                            //订单优惠券
                            int couponAmountV = 0;
                            if (couponMapList.size() > 0 && allCouponAmount > 0) {
                                String gsKey = goodsPo.getGoodsId().toString();
                                if (!StringUtils.isEmpty(goodsPo.getSkuId())) {
                                    gsKey = goodsPo.getGoodsId().toString() + goodsPo.getSkuId().toString();
                                }
                                for (Map<String, Object> goodsCouponData : goodsCouponList) {
                                    if (gsKey.equals(goodsCouponData.get("goodsSku"))) {
                                        couponAmountV = Integer.valueOf(goodsCouponData.get("couponAmount").toString());
                                        consumptionId = goodsCouponData.get("consumptionId").toString();
                                        couponId = goodsCouponData.get("couponId").toString();

                                    }
                                }
                            }
                            couponOrderAmount += couponAmountV;
                            //订单商品积分
                            int goodsScore = 0;
                            if ("1".equals(scoreStr) && score > 0) {
                                String gsKey = goodsPo.getGoodsId().toString();
                                if (!StringUtils.isEmpty(goodsPo.getSkuId())) {
                                    gsKey = goodsPo.getGoodsId().toString() + goodsPo.getSkuId().toString();
                                }
                                for (Map<String, Object> goodsScoreData : goodsScoreList) {
                                    if (gsKey.equals(goodsScoreData.get("goodsSku"))) {
                                        goodsScore = Integer.valueOf(goodsScoreData.get("goodsScore").toString());
                                    }
                                }
                            }

                            integralPaymentAmount = integralPaymentAmount + goodsScore;

                            orderGoodsPo.setCouponAmount("" + couponAmountV);
                            orderGoodsPo.setPaymentPoints(goodsScore);
                            orderGoodsPo.setAmountCent(goodsPo.getAmountCent());
                            orderGoodsPo.setCustomerId(customerId);
                            orderGoodsPo.setBuyCount(goodsPo.getBuyCount());
                            orderGoodsPo.setGoodsId(goodsPo.getGoodsId());
                            orderGoodsPo.setGoodsCover(goodsPo.getGoodsCover());
                            orderGoodsPo.setGoodsName(goodsPo.getGoodsName());
                            orderGoodsPo.setSkuId(goodsPo.getSkuId());
                            orderGoodsPo.setSkuKey(goodsPo.getSkuKey());
                            orderGoodsPo.setSkuValue(goodsPo.getSkuValue());
                            orderGoodsPo.setShippingFee(goodsPo.getGoodsFreightCent().intValue());
                            orderGoodsPo.setSalerId(goodsPo.getDistributor());
                            orderGoodsPo.setGoodsType(goodsPo.getGoodsType());
                            orderGoodsPo.setMallsAmount(mallsAmount);
                            orderGoodsPo.setMallsGoodsId(goodsPo.getMallsGoodsId());
                            orderGoodsPo.setAuthor(goodsPo.getAuthor());
                            orderGoodsPoList.add(orderGoodsPo);
                            allGoodsNum += goodsPo.getBuyCount();
                        }
                        distributor = goodsPo.getDistributor();
                        author = goodsPo.getAuthor();
                    }
                    goodsFee = orderAmount;
                    orderAmount = orderAmount + goodsFreight;
                    allScore = allScore + integralPaymentAmount;

                    ShoppingCartGoodsPo goodsPo = new ShoppingCartGoodsPo();
                    goodsPo.setGoodsFreightCent(goodsFreight);
                    map.put("consumptionId", consumptionId);
                    map.put("couponId", couponId);
                    map.put("couponAmount", couponOrderAmount);
                    map.put("goodsAmountCent", goodAmount);
                    map.put("orderTotalPriceCent", orderAmount);
                    map.put("orderAmountCent", orderAmount - integralPaymentAmount - couponOrderAmount);
                    map.put("goods", goodsPo);
                    map.put("address", orderAddressDto);
                    map.put("orderRebate", "0");
                    map.put("orderGoodsType", 1);
                    map.put("paySn", paySn);
                    map.put("distributor", distributor);
                    map.put("remark", remark);
                    map.put("author", author);
                    map.put("integralPaymentAmount", integralPaymentAmount);
                    map.put("belongId", StringUtils.isEmpty(belongId) ? orgId : belongId);
                    if (StringUtils.isEmpty(map.get("storeId"))) {
                        map.put("storeId", map.get("belongId"));
                    }
                    purchaseProcessDao.insertOrderByMap(map);
                    totalFee = totalFee + orderAmount;
//                    Long orderId = Long.valueOf(map.get("orderId").toString());
                    Long orderId = (Long) map.get("orderId");
                    String purchaseOrderSn = TransactionOrderUtil.TYPE_SHOP + TransactionOrderUtil.getPrimaryKey();

                    for (MerchantOrderGoodsPo goods : orderGoodsPoList) {
                        goods.setOrderId(orderId);
                        //写入订单商品留言
                        if (null != map.get("goodsRemarkList")) {
                            List<Map<String, Object>> goodsRemarkList = (List) map.get("goodsRemarkList");
                            if (goodsRemarkList.size() > 0) {
                                for (Map<String, Object> da : goodsRemarkList) {
                                    if (null != da.get("goodsId") && goods.getGoodsId().toString().equals(da.get("goodsId").toString())
                                            && null != da.get("goodsRemark")) {
                                        if (da.get("skuId") == null || (da.get("skuId") != null && Long.valueOf(da.get("skuId").toString()).equals(goods.getSkuId()))) {
                                            List<Map<String, Object>> goodsRemark = (List) da.get("goodsRemark");
                                            if (goodsRemark.size() > 0) {
                                                goods.setGoodsRemark(JSON.toJSONString(goodsRemark));
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        purchaseProcessDao.insertOrderGoodsByPoBatch(goods);
                        if (goods.getPaymentPoints() > 0) {
                            //记录金币变动记录
                            Map<String, Object> scoreLog = new HashMap<>();
                            scoreLog.put("customerId", map.get("customerId"));
                            scoreLog.put("score", goods.getPaymentPoints());
                            scoreLog.put("type", 0);
                            scoreLog.put("orderSn", orderSn);
                            scoreLog.put("recId", goods.getRecId());
                            purchaseProcessDao.addScoreLog(scoreLog);
                        }
                        //判断供货商品
                        if (null != goods.getMallsGoodsId()) {
                            map.put("recId", goods.getRecId());
                            map.put("mallsGoodsId", goods.getMallsGoodsId());
                            map.put("purchaseOrderSn", purchaseOrderSn);
                            map.put("orderSn", orderSn);
                            map.put("mallsAmount", goods.getMallsAmount() == null ? 0 : goods.getMallsAmount());
                            Map mallsGoodsInfo = goodsService.getGoodsInfo(goods.getMallsGoodsId().toString());
                            map.put("goodsName", mallsGoodsInfo.get("goodsName"));
                            map.put("goodsNum", goods.getBuyCount());
                            map.put("goodsImage", mallsGoodsInfo.get("goodsCover"));
                            map.put("shippingFee", goods.getShippingFee());
                            purchaseProcessDao.addPurchaseOrder(map);
                        }
                    }
                    orderIds.add(orderId);

                    //组装参数请求签名
                    Map<String, Object> tmpOrderGoods = new HashMap<>();
                    tmpOrderGoods.put("orderSn", orderSn);
                    tmpOrderGoods.put("goodsList", orderGoodsPoList);
                    tmpOrderGoods.put("score", integralPaymentAmount);
                    tmpOrderGoods.put("couponAmount", couponOrderAmount);
                    tmpOrderGoods.put("orderAmount", orderAmount);
                    signData.add(tmpOrderGoods);
                    map.put("objectId", orderSn);
                    mallService.addToDealData(map, 3);

                    if (!StringUtils.isEmpty(consumptionId) && !StringUtils.isEmpty(couponId)) {
                        //使用优惠券
                        couponH5Service.useConsumption(consumptionId, (int) (orderAmount - couponOrderAmount), orderSn, allGoodsNum, couponOrderAmount, 0, couponCustomerInfo);
                    }
                }
            }

        }

        //扣金币
        purchaseProcessDao.updateScoreByCustomerId((long) allScore, customerId);

        List<Map<String, Object>> recIds = purchaseProcessDao.getRecIdByOrderSn(paySn);
        for (Map<String, Object> recId : recIds) {
            this.exercise(recId);
        }
        Map<String, Object> total = new HashMap<>();
        total.put("goods", goodsFee);
        total.put("order", totalFee);
        total.put("signData", signData);
        total.put("type", type);
        total.put("score", allScore);
        return total;
    }

    /**
     * 购买小b商品(1.11新增大b也会产生分润)
     */
    private String buyGoodsFromSales(Map<String, Long> totalFee, String orgId, String orderSn, Integer score, String customerId, String distributor, int type, String openid, boolean recommend) throws GlobalException {
        // 直接购买小b商品，产生推荐费和服务费
        Long id = totalFee.get("goodsId");
        Map<String, Integer> reverseProfitModel = mallBoomDao.getReverseProfitModel(orgId);// 返润模式
        Integer serviceRatio;// 商品服务费占比例,eg:50
        Integer recommendRatio;// 商品推荐费比例
        Integer unhappen;// 未产生费用给谁 1-商家2-机构
        if (reverseProfitModel == null) {
            // 机构没有设置返润模式
            serviceRatio = 50;
            recommendRatio = 50;
            unhappen = 1;
        } else {
            serviceRatio = reverseProfitModel.get("serviceRatio");
            recommendRatio = reverseProfitModel.get("recommendRatio");
            unhappen = reverseProfitModel.get("unhappen");
        }
        String rebateStr = purchaseProcessDao.getPromotionStrRebateByGoodsId(id);// 总返利,eg:20
        if (StringUtils.isEmpty(rebateStr)) {
            rebateStr = "0";
        }
        Double rebate = Double.valueOf(rebateStr);
        double i = rebate * serviceRatio.doubleValue() / 100;// 服务费比例,eg:10
        double j = rebate * recommendRatio.doubleValue() / 100;// 服务费比例,eg:10
        double iv = totalFee.get("goods").doubleValue() * i / 100;// 服务费
        double jv = totalFee.get("goods").doubleValue() * j / 100;// 推荐费
        int sharePrice = new BigDecimal(iv).setScale(0, BigDecimal.ROUND_HALF_EVEN).intValue();// 返利值(服务费)1
        int recomPrice = new BigDecimal(jv).setScale(0, BigDecimal.ROUND_HALF_EVEN).intValue();// 返利值(推荐费)2
        double goodsAllRebate = totalFee.get("goods").doubleValue() * rebate / 100;
        int totalPrice = new BigDecimal(goodsAllRebate).setScale(0, BigDecimal.ROUND_HALF_EVEN).intValue();// 总返利值
        int platformPrice = totalPrice - sharePrice - recomPrice;// 返利值(平台费)3
        if (platformPrice < 0) {
            // 推荐费和服务费都进位，平台费为0，导致总返利减去推荐费和服务费结果为-1，需要调整费用
            platformPrice = 0;
            recomPrice = totalPrice - sharePrice;
        }
        int goodsTotalPrice = totalFee.get("order").intValue();// 商品价格+运费
//        Map<String, Long> platformRateMap = purchaseProcessDao.getPlatformRateByOrgId(orgId);
        // lh抽成
//        Integer linkerTake = platformRateMap.get("linkerTake").intValue();
        Integer linkerTake = 0;
        // 大b抽成
//        Integer unionBarleyTake = platformRateMap.get("unionBarleyTake").intValue();
        Integer unionBarleyTake = 0;
        // 总抽成
        Integer platformRate = linkerTake + unionBarleyTake;

        if (score != null) {
            // 如果要使用积分
            double v = goodsTotalPrice - (totalFee.get("goods").doubleValue() * rebate) / (100 - platformRate);
            // 可用积分，直接取整
            int l = (int) v;
            if (score > l) {
                // 可使用积分限制
                score = l;
            }
        } else {
            score = 0;
        }
        totalFee.put("score", score.longValue());
        // 用户实付金额
        int pay = goodsTotalPrice - score;
        // 更新订单表实付金额
        purchaseProcessDao.updateOrderAmountByOrderSn(orderSn, pay);
        // 联汇抽成
        double v2 = pay * linkerTake.doubleValue() / 100;
        int linkerFee = new BigDecimal(v2).setScale(0, BigDecimal.ROUND_HALF_EVEN).intValue();
        // 大麦抽成
        double v3 = pay * unionBarleyTake.doubleValue() / 100;
        int unionBarleyFee = new BigDecimal(v3).setScale(0, BigDecimal.ROUND_HALF_EVEN).intValue();
        // 平台费3
        int platformFee = linkerFee + unionBarleyFee;
        // 商品收益=订单总金额-总返利-平台费4
        int income = pay - totalPrice - platformFee;
        // 1-sharePrice-分享人（联汇子账户） 2-recomPrice-推荐人（联汇子账户）3-platformFee-联汇（联汇子账户） 4-income-商品拥有者（小b账户）
        // 1+2+3 先打到联汇账户，多出来的打给小b账户，然后联汇打积分抵扣的金额给小b账户
        int lh = totalPrice + platformFee;
        if (pay < lh) {
            throw GlobalException.build("用户支付金额不足");
        }
        // 上级id
        String pid = purchaseProcessDao.getPidByCid(customerId);
        // 是否产出推荐费给推荐人
        boolean ifRf = !StringUtils.isEmpty(pid) && recomPrice != 0 && !pid.equals(customerId);

        // 若本没有推荐费，且有临时推荐人，那么先将临时推荐人作为推荐人
        if (!ifRf && recommend) {
            ifRf = true;
            pid = distributor;
        }

        if (!StringUtils.isEmpty(pid)) {
            // 推广员不返推荐费
            Map<String, Long> role = purchaseProcessDao.getUserRoleMapByCustomerId(pid);
            Long a = role.get("a");
            Long b = role.get("b");
            Long c = role.get("c");
            if (a == 0 && b == 1 && c == 0) {
                ifRf = false;
            }
            if (c == 0) {
                ifRf = false;
            }
        }

        // 是否产出服务费给分享人
        boolean ifFw = !StringUtils.isEmpty(distributor) && sharePrice != 0 && !distributor.equals(customerId);
        // 商品所属人id
        String belongId = purchaseProcessDao.getBelongIdByGoodsId(id);
        // 是否为大b需要反润的商品(1.11新增)
        boolean ifRebateToOrg = false;
        if (StringUtils.isEmpty(belongId) && type == 1) {
            ifRebateToOrg = true;
        }
        String linkId = "";
        // 请求地址
        String url = wcPayProperties.getPayurl() + "/pay/wcpay";
        // 是否需要分润(暂无)
        boolean needShare = false;
        if (ifFw || ifRf) {
            needShare = true;
        }
        Map<String, Object> req = this.getWxPayParam(openid, orderSn, String.valueOf(pay), orgId, needShare);
        // 请求支付网关
        String result = "";
        try {
            // 积分抵扣为0元
            if (pay != 0) {
                // 请求网关
                result = httpService.doPost(url, req);
                // 处理结果
                result = this.callResultProcessWx(result);
            }
        } catch (Exception e) {
            LOGGER.error("支付网关调用异常" + e);
            throw GlobalException.build("支付网关调用异常");
        }
        // 系统内分钱

        // 分享人是否是普通用户
        boolean distributorIsNormal = false;
        if (ifFw) {
            distributorIsNormal = this.getUserRole(distributor);
        }
        List<Map<String, Object>> tradeInfos = new ArrayList<>();
        if (score != 0) {
            // 积分支出
            // 以后可以改为构造器 new TradeInfo(args...);
            Map<String, Object> tradeInfo = new HashMap<>();
            tradeInfo.put("from", customerId);
            tradeInfo.put("to", ifRebateToOrg ? orgId : belongId);
            tradeInfo.put("amount", score);
            tradeInfo.put("tradeType", 0);
            tradeInfo.put("payType", 2);
            tradeInfo.put("receiveRole", ifRebateToOrg ? 1 : 2);
//                TradeInfo tradeInfo = new TradeInfo(customerId, belongId, score, 0, 2, 2);
            tradeInfos.add(tradeInfo);
        }

        // 组装、获取各账号的账号类型：ABC，和账户id
//        Map<String, AccountInfo> nameMap = subAccountList.stream()
//                .collect(Collectors.toMap(AccountInfo::getName, x -> x));
        String serviceAccountType = "";
        String serviceAccount = "";
        String recommendAccountType = "";
        String recommendAccount = "";
        if (ifFw) {
//            serviceAccountType = nameMap.get(FeeConstants.SERVICE_FEE).getType();
//            serviceAccount = nameMap.get(FeeConstants.SERVICE_FEE).getAccount();
        }
        if (ifRf) {
//            recommendAccountType = nameMap.get(FeeConstants.RECOMMEND_FEE).getType();
//            recommendAccount = nameMap.get(FeeConstants.RECOMMEND_FEE).getAccount();
        }
//        String orgDrawAccountType = nameMap.get(FeeConstants.ORG_DRAW_FEE).getType();
//        String orgDrawAccount = nameMap.get(FeeConstants.ORG_DRAW_FEE).getAccount();
        String orgDrawAccountType = "";
        String orgDrawAccount = "";
//        String linkDrawAccountType = nameMap.get(FeeConstants.LINK_DRAW_FEE).getType();
//        String linkDrawAccount = nameMap.get(FeeConstants.LINK_DRAW_FEE).getAccount();
        String linkDrawAccountType = "";
        String linkDrawAccount = "";

        Integer unhappenFee = 0;
        if (ifFw && ifRf) {
            // 服务
            Map<String, Object> tradeInfo1 = new HashMap<>();
            tradeInfo1.put("from", customerId);
            tradeInfo1.put("to", distributor);
            tradeInfo1.put("amount", sharePrice);
            // 积分交易类型0-金币抵扣，1-商品服务费，2 -金币退回
            tradeInfo1.put("tradeType", distributorIsNormal ? 1 : 2);
            // 支付方式1-rmb，2-积分
            tradeInfo1.put("payType", distributorIsNormal ? 2 : 1);
            tradeInfo1.put("receiveRole", 5);
            tradeInfo1.put("accountType", serviceAccountType);
            tradeInfo1.put("receiveAccount", serviceAccount);
            tradeInfos.add(tradeInfo1);
            // 推荐
            Map<String, Object> tradeInfo2 = new HashMap<>();
            tradeInfo2.put("from", customerId);
            tradeInfo2.put("to", pid);
            tradeInfo2.put("amount", recomPrice);
            // 交易类型：0-提现，1-商品成交收益，2-商品服务费，3-商品推荐费，4-商品平台费，5-开通联盟商家平台费，6-开通联盟商家收益，7-开通加盟代理平台费，8-开通加盟代理收益，9-商城商品平台费，10-商城商品收益，11-提现手续费
            tradeInfo2.put("tradeType", 3);
            tradeInfo2.put("payType", 1);
            tradeInfo2.put("receiveRole", 5);
            tradeInfo2.put("accountType", recommendAccountType);
            tradeInfo2.put("receiveAccount", recommendAccount);
            tradeInfos.add(tradeInfo2);
        } else if (ifFw) {
            // 仅服务费
            Map<String, Object> tradeInfo = new HashMap<>();
            tradeInfo.put("from", customerId);
            tradeInfo.put("to", distributor);
            tradeInfo.put("amount", sharePrice);
            tradeInfo.put("tradeType", distributorIsNormal ? 1 : 2);
            tradeInfo.put("payType", distributorIsNormal ? 2 : 1);
            tradeInfo.put("receiveRole", 5);
            tradeInfo.put("accountType", serviceAccountType);
            tradeInfo.put("receiveAccount", serviceAccount);
            tradeInfos.add(tradeInfo);
            unhappenFee += recomPrice;

        } else if (ifRf) {
            // 仅推荐费
            Map<String, Object> tradeInfo = new HashMap<>();
            tradeInfo.put("from", customerId);
            tradeInfo.put("to", pid);
            tradeInfo.put("amount", recomPrice);
            tradeInfo.put("tradeType", 3);
            tradeInfo.put("payType", 1);
            tradeInfo.put("receiveRole", 5);
            tradeInfo.put("accountType", recommendAccountType);
            tradeInfo.put("receiveAccount", recommendAccount);
            tradeInfos.add(tradeInfo);
            unhappenFee += sharePrice;
        } else {
            // 两笔钱都无人认领
            unhappenFee += recomPrice + sharePrice;
        }
        if (unhappen == 1) {
            // 未产生费用给商家
            income += unhappenFee;
        } else if (unhappen == 2 && unhappenFee > 0) {
            // 未产生费用给平台
            unionBarleyFee += unhappenFee;
        }
        unionBarleyFee += platformPrice;
        if (unionBarleyFee != 0) {
            // 大b平台费
            Map<String, Object> tradeInfo1 = new HashMap<>();
            tradeInfo1.put("from", customerId);
            tradeInfo1.put("to", orgId);
            tradeInfo1.put("amount", unionBarleyFee);
            tradeInfo1.put("tradeType", 4);
            tradeInfo1.put("payType", 1);
            tradeInfo1.put("receiveRole", 1);
            tradeInfo1.put("accountType", orgDrawAccountType);
            tradeInfo1.put("receiveAccount", orgDrawAccount);
            tradeInfos.add(tradeInfo1);
        }
        if (linkerFee != 0) {
            // 联汇平台费
            Map<String, Object> tradeInfo2 = new HashMap<>();
            tradeInfo2.put("from", customerId);
            tradeInfo2.put("to", linkId);
            tradeInfo2.put("amount", linkerFee);
            tradeInfo2.put("tradeType", 9);
            tradeInfo2.put("payType", 1);
            tradeInfo2.put("receiveRole", 0);
            tradeInfo2.put("accountType", linkDrawAccountType);
            tradeInfo2.put("receiveAccount", linkDrawAccount);
            tradeInfos.add(tradeInfo2);
        }
        // 给小b的商品收益
//        if (income != 0) {
        Map<String, Object> tradeInfo = new HashMap<>();
        tradeInfo.put("from", customerId);
        tradeInfo.put("to", ifRebateToOrg ? orgId : belongId);
        tradeInfo.put("amount", income);
        // 交易类型：0-提现，1-商品成交收益，2-商品服务费，3-商品推荐费，4-商品平台费，5-开通联盟商家平台费，6-开通联盟商家收益，7-开通加盟代理平台费，8-开通加盟代理收益，9-商城商品平台费，10-商城商品收益，11-提现手续费
        tradeInfo.put("tradeType", 1);
        // 支付方式1-rmb，2-积分
        tradeInfo.put("payType", 1);
        tradeInfo.put("receiveRole", ifRebateToOrg ? 1 : 2);
        tradeInfo.put("accountType", "");
//        tradeInfo.put("receiveAccount", belongAccountNumber);
        tradeInfos.add(tradeInfo);
//        }
        // 分账数据
        stringRedisTemplate.opsForValue().set(ACS_CREATE_ORDER_INFO + orderSn, JSON.toJSONString(tradeInfos), 30, TimeUnit.DAYS);
        // 签名数据
        stringRedisTemplate.opsForValue().set(ACS_CREATE_ORDER_RESULT + orderSn, result, 60, TimeUnit.MINUTES);
        return result;

    }

    /**
     * 购买大b商品
     */
    private String buyGoodsFromOrg(Map<String, Long> totalFee, String orgId, String orderSn, Integer score, String customerId, String openid) throws GlobalException {
        // 购买大b商品，产生平台费
        Long order = totalFee.get("order");
        if (score != null) {
            // 使用积分
            if (score > order) {
                // 使用积分不超过订单总价
                score = order.intValue();
            }
        } else {
            score = 0;
        }
        totalFee.put("score", score.longValue());
        // 实付金额
        int pay = order.intValue() - score;
        purchaseProcessDao.updateOrderAmountByOrderSn(orderSn, pay);
//        Map<String, Long> platformRateMap = purchaseProcessDao.getPlatformRateByOrgId(orgId);
//        Integer linkerTake = platformRateMap.get("linkerTake").intValue();
//        Integer unionBarleyTake = platformRateMap.get("unionBarleyTake").intValue();
        Integer unionBarleyTake = 0;
        Integer linkerTake = 0;
        double v1 = pay * unionBarleyTake.doubleValue() / 100;
        int unionBarleyFee = new BigDecimal(v1).setScale(0, BigDecimal.ROUND_HALF_EVEN).intValue();
        double v2 = pay * linkerTake.doubleValue() / 100;
        int linkerFee = new BigDecimal(v2).setScale(0, BigDecimal.ROUND_HALF_EVEN).intValue();
        // 平台费
        int platformFee = unionBarleyFee + linkerFee;
        // 收益
        int income = pay - platformFee;
        Map<String, Object> reqMap = new HashMap<>();
//        String orgAccountNumber = purchaseProcessDao.getCustomerAccountNumberByCustomerId(orgId);
        String orgAccountNumber = "";

//        List<AccountInfo> subAccountList = new ArrayList<>();
//        Map<String, Integer> subAccountMap = new HashMap<>();
//        subAccountMap.put(FeeConstants.LINK_DRAW_FEE, linkerFee);
//        subAccountMap.put(FeeConstants.ORG_DRAW_FEE, unionBarleyFee);
//        for (String s : subAccountMap.keySet()) {
//            subAccountList.add(this.getAccountMap(s, subAccountMap.get(s), orgId));
//        }
//        Map<String, Integer> collect = subAccountList.stream()
//                .collect(Collectors.groupingBy(AccountInfo::getCustomerId, Collectors.summingInt(AccountInfo::getAmount)));

        if (score != 0) {
            // 余额支付金额(积分抵扣金额)
            reqMap.put("balanceAmount", score);
            List<Map<String, Object>> balanceSplitItems = new ArrayList<>();
            Map<String, Object> balanceSplitItem = new HashMap<>();
            balanceSplitItem.put("customerId", orgId);
            if (StringUtils.isEmpty(orgAccountNumber)) {
//                throw GlobalException.build("大b暂未绑卡");
            }
            balanceSplitItem.put("customerAccountNumber", orgAccountNumber);
            balanceSplitItem.put("splitAmount", score);
            balanceSplitItem.put("note", "货架商城商品收益-积分抵扣");
            balanceSplitItem.put("orderId", orderSn);
            balanceSplitItems.add(balanceSplitItem);
            // 余额分账明细，JSON字符串
            reqMap.put("balanceSplitItems", JSON.toJSONString(balanceSplitItems));
        }
        // 现金支付金额
        reqMap.put("cashAmount", pay);
        List<Map<String, Object>> cashSplitItems = new ArrayList<>();
//        String linkId = purchaseProcessDao.getLinkId();
        String linkId = "";
//        String feeId = this.getCustomerIdByFeeTypeAndOrdId(FeeConstants.SERVICE_FEE, orgId);
        String feeId = "";
//        String linkAccountNumber = purchaseProcessDao.getCustomerAccountNumberByCustomerId(linkId);
        // 余额支出账户
//        String feeCustomerId = purchaseProcessDao.getCustomerAccountNumberByCustomerId(feeId);
        String feeCustomerId = "";
        if (platformFee != 0) {
            // 用户钱一部分到lh(余额支出账户)
//            collect.forEach((x, y) -> {
//                Map<String, Object> cashSplitItem = new HashMap<>();
//                cashSplitItem.put("customerId", x);
//                cashSplitItem.put("customerAccountNumber", purchaseProcessDao.getCustomerAccountNumberByCustomerId(x));
//                cashSplitItem.put("splitAmount", y);
//                cashSplitItem.put("note", "货架商城商品平台费");
//                cashSplitItem.put("orderId", orderSn);
//                cashSplitItems.add(cashSplitItem);
//            });
        }
        // 用户钱到大b
        Map<String, Object> cashSplitItem = new HashMap<>();
        cashSplitItem.put("customerId", orgId);
        cashSplitItem.put("customerAccountNumber", orgAccountNumber);
        cashSplitItem.put("splitAmount", income);
        cashSplitItem.put("note", "货架商城商品收益");
        cashSplitItem.put("orderId", orderSn);
        cashSplitItems.add(cashSplitItem);
        reqMap.put("cashSplitItems", JSON.toJSONString(cashSplitItems));
        // 支付用户ID
        reqMap.put("customerId", customerId);
        // 商品描述
        String goodsNames = purchaseProcessDao.getGoodsNamesByOrderSn(orderSn);
        reqMap.put("goodsName", goodsNames);
        // 支付用户OPENID
//        String openId = purchaseProcessDao.getOpenIdByCustomerId(customerId);
        String openId = openid;
        reqMap.put("openID", openId);
        // 平台订单ID
        reqMap.put("orderSn", orderSn);
        // 收款用户帐号(收款用户为机构会员时必填，机构结算标识)(大b账号)
        reqMap.put("payeeAccountNumber", orgAccountNumber);
        // 收款用户ID
        reqMap.put("payeeUserID", orgId);
        // 余额支出账户
        reqMap.put("feeCustomerId", feeCustomerId);
//        String url = wcPayProperties.getAcsurl() + WcPayConstant.TRADE_PAY_ORDER;
        String url = wcPayProperties.getPayurl() + "/pay/wcpay";
        // 请求中金网关
        String result = "";
//        Map<String, Object> req = this.getWxPayParam(openId, orderSn, String.valueOf(pay), orgId, false);
        Map<String, Object> req = this.getWxPayParam(openId, orderSn, String.valueOf(pay), orgId, false);
        try {
//            result = httpService.doPost(url, JSON.toJSONString(reqMap), WcPayConstant.JSON);
            // 用积分抵扣成0元
            if (pay != 0) {
                result = httpService.doPost(url, req);
//            result = this.callResultProcess(result);
                result = this.callResultProcessWx(result);
                // 保存当前平台费比例
                purchaseProcessDao.saveTlPayReqParam(orderSn, null, linkerTake.toString(), unionBarleyTake.toString());
            }
        } catch (Exception e) {
            LOGGER.error("支付网关调用异常" + e);
            throw GlobalException.build("支付网关调用异常");
        }
        // 系统内分钱
//        Map<String, AccountInfo> nameMap = subAccountList.stream()
//                .collect(Collectors.toMap(AccountInfo::getName, x -> x));
//        String orgDrawAccountType = nameMap.get(FeeConstants.ORG_DRAW_FEE).getType();
//        String orgDrawAccount = nameMap.get(FeeConstants.ORG_DRAW_FEE).getAccount();
        String orgDrawAccountType = "";
        String orgDrawAccount = "";
//        String linkDrawAccountType = nameMap.get(FeeConstants.LINK_DRAW_FEE).getType();
//        String linkDrawAccount = nameMap.get(FeeConstants.LINK_DRAW_FEE).getAccount();
        String linkDrawAccountType = "";
        String linkDrawAccount = "";

        List<Map<String, Object>> tradeInfos = new ArrayList<>();
        // 大b商品收益
        Map<String, Object> tradeInfo1 = new HashMap<>();
        tradeInfo1.put("from", customerId);
        tradeInfo1.put("to", orgId);
        tradeInfo1.put("amount", income);
        tradeInfo1.put("tradeType", 10);
        tradeInfo1.put("payType", 1);
        tradeInfo1.put("receiveRole", 1);
        tradeInfo1.put("accountType", "");
        tradeInfo1.put("receiveAccount", orgAccountNumber);
        tradeInfos.add(tradeInfo1);
        if (score != 0) {
            // 积分支出
            Map<String, Object> tradeInfo = new HashMap<>();
            tradeInfo.put("from", customerId);
            tradeInfo.put("to", orgId);
            tradeInfo.put("amount", score);
            tradeInfo.put("tradeType", 0);
            tradeInfo.put("payType", 2);
            tradeInfo.put("receiveRole", 1);
            tradeInfo1.put("accountType", "");
            tradeInfo1.put("receiveAccount", orgAccountNumber);
            tradeInfos.add(tradeInfo);
        }
        // lh平台费
        if (linkerFee > 0) {
            Map<String, Object> tradeInfo2 = new HashMap<>();
            tradeInfo2.put("from", customerId);
            tradeInfo2.put("to", linkId);
            tradeInfo2.put("amount", linkerFee);
            tradeInfo2.put("tradeType", 9);
            tradeInfo2.put("payType", 1);
            tradeInfo2.put("receiveRole", 0);
            tradeInfo2.put("accountType", linkDrawAccountType);
            tradeInfo2.put("receiveAccount", linkDrawAccount);
            tradeInfos.add(tradeInfo2);
        }
        // 大b平台费
        if (unionBarleyFee > 0) {
            Map<String, Object> tradeInfo3 = new HashMap<>();
            tradeInfo3.put("from", customerId);
            tradeInfo3.put("to", orgId);
            tradeInfo3.put("amount", unionBarleyFee);
            tradeInfo3.put("tradeType", 4);
            tradeInfo3.put("payType", 1);
            tradeInfo3.put("receiveRole", 1);
            tradeInfo3.put("accountType", orgDrawAccountType);
            tradeInfo3.put("receiveAccount", orgDrawAccount);
            tradeInfos.add(tradeInfo3);
        }
        // 分账数据
        stringRedisTemplate.opsForValue().set(ACS_CREATE_ORDER_INFO + orderSn, JSON.toJSONString(tradeInfos), 30, TimeUnit.DAYS);
        // 签名数据
        stringRedisTemplate.opsForValue().set(ACS_CREATE_ORDER_RESULT + orderSn, result, 60, TimeUnit.MINUTES);
        return result;
    }

    /**
     * 调用结果处理(中金)
     */
    @Override
    public String callResultProcess(String result) throws GlobalException {
        if (StringUtils.isEmpty(result)) {
            throw GlobalException.build("网关调用失败");
        }
        LOGGER.info(result);
        Map resMap = (Map) JSON.parse(result);
        if (!resMap.containsKey("code")) {
            throw GlobalException.build("网关调用失败:" + resMap.get("msg"));
        }
        if (!"200".equals(resMap.get("code"))) {
            throw GlobalException.build("网关调用失败:" + resMap.get("msg"));
        }
        if (!resMap.containsKey("data")) {
            throw GlobalException.build("网关调用失败:" + resMap.get("msg"));
        }
        Map data = (Map) resMap.get("data");
        if (!data.containsKey("authCode")) {
            throw GlobalException.build("网关调用失败:" + resMap.get("msg"));
        }
        return (String) data.get("authCode");
    }

    /**
     * 调用结果处理(微信)
     */
    @Override
    public String callResultProcessWx(String result) throws GlobalException {
        if (StringUtils.isEmpty(result)) {
            throw GlobalException.build("操作失败");
        }
        LOGGER.info(result);
        Object parse = JSON.parse(result);
        Map ret = (Map) parse;
        if ((Integer) ret.get("rt") != 1) {
            throw GlobalException.build("支付网关调用失败");
        }
        //noinspection unchecked
        Map<String, Object> retInfo = (Map) ret.get("object");
        retInfo.put("package", "prepay_id=" + retInfo.get("prepayId"));
        return JSON.toJSONString(retInfo);
    }

    /**
     * 根据用户id判断是否为普通用户(需要分金币的用户)
     */
    @Override
    public boolean getUserRole(String customerId) {
        Map<String, Long> role = purchaseProcessDao.getUserRoleMapByCustomerId(customerId);
        Long a = role.get("a");
        Long b = role.get("b");
        Long c = role.get("c");
        return c != 1;
    }

    /**
     * 生成业务单号
     * 前缀+13位时间戳+用户id
     */
    @Override
    public String generateBusiSn(Integer tradeType, String customerId) {
        String prefix = "";
        switch (tradeType) {
            // rmb交易类型：0-提现，1-商品成交收益，2-商品服务费，3-商品推荐费，4-商品平台费(大b)，5-开通联盟商家平台费，
            // 6-开通联盟商家收益，7-开通加盟代理平台费，8-开通加盟代理收益，9-商品平台费(联汇)，10-商城商品收益，11-提现手续费
            case 1:
            case 10:
                prefix = "AB";
                break;
            case 2:
                prefix = "AE";
                break;
            case 3:
                prefix = "AF";
                break;
            case 4:
                prefix = "AC";
                break;
            case 5:
                prefix = "BD";
                break;
            case 6:
                prefix = "BB";
                break;
            case 7:
                prefix = "CD";
                break;
            case 8:
            case 13:
                prefix = "CB";
                break;
            case 9:
                prefix = "AD";
                break;
            case 12:
                prefix = "F";
                break;
            case 20://开通联盟商家平台抽成（大麦）
                prefix = "BC";
                break;
            case 21://开通加盟代理平台抽成（大麦）
                prefix = "CC";
                break;
            case 22://vip
                prefix = "V";
                break;
            case 31://31-体检费用
                prefix = "I";
                break;
            case 32://32-体检分佣
                prefix = "IB";
                break;
            case 33://33-体检充值
                prefix = "J";
            default:
                break;
        }
        return prefix + System.currentTimeMillis() + customerId;
    }

    private void updateExerciseRecord(Map<String, Object> map, String customerId) {
        // 更新状态
        purchaseProcessDao.updateExerciseRecordByRecId(map);
        // 判断赠品中是否有懂小姐体检券
        Integer integer = purchaseProcessDao.countDongExerciseRecordByRecId(map);
        if (integer > 0) {
            // 懂小姐
            String url = systemProperties.getDongUrl() + DongConstant.USER_GOODS_GIVE_COUPONS;
            Map<String, Object> reqMap = new HashMap<>();
            reqMap.put("couponType", "3");
            reqMap.put("orderId", map.get("orderId"));
            reqMap.put("userId", customerId);
            String result = "";
            LOGGER.info("exercise===req[{}]===url[{}]", JSON.toJSONString(reqMap), url);
            try {
                result = httpService.doPost(url, reqMap);
            } catch (URISyntaxException | IOException e) {
                LOGGER.error("懂小姐接口调用异常");
            }
            LOGGER.info("exercise===res[{}]", result);
        }
    }

    @Async
    @Override
    public void buyGoodsSmsPush(List<Map<String, Object>> goodsIdAndBuyNum, String orgId) {
        // 商品购买推送 只有普通商品成交后进行推送，知识付费商品、报名等等其他付费项不进行推送
        List<String> belongIdList = goodsIdAndBuyNum.stream()
                .map(x -> (String) x.get("belongId"))
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
        // 提醒手机号
        StringBuilder remindPhone = new StringBuilder();
        Map<String, Object> map = new HashMap<>();
        map.put("businessType", "9010");
        if (belongIdList.contains("")) {
            // 包含大b的商品，取大b的手机号
            String orgRemindPhone = purchaseProcessDao.getRemindPhoneByOrgId(orgId);
            if (!StringUtils.isEmpty(orgRemindPhone)) {
                remindPhone.append(orgRemindPhone).append(",");
            }
        }
        // 小b商品手机号
        String belongRemindPhone = purchaseProcessDao.getRemindPhoneByBelongIdList(belongIdList);
        if (!StringUtils.isEmpty(belongRemindPhone)) {
            remindPhone.append(belongRemindPhone);
        }
        if (remindPhone.length() == 0) {
            return;
        }
        map.put("mobilNumber", remindPhone.toString());
        map.put("params", "");
        String s = smsService.sendMsg(orgId, map);
        LOGGER.info("smsService.sendMsg.result===[{}]", s);
    }

    /**
     * 根据机构和费用类型查询分账配置账号
     *
     * @param type  见FeeConstants
     * @param orgId 机构id
     */
    @Override
    public String getAccountNumByFeeTypeAndOrdId(String type, String orgId) throws GlobalException {
        String account = purchaseProcessDao.getAccountByFeeTypeAndOrdId(type, orgId);
        if (StringUtils.isEmpty(account)) {
            purchaseProcessDao.insertAcsOrgDefaultConfig(orgId);
            account = purchaseProcessDao.getAccountByFeeTypeAndOrdId(type, orgId);
        }
        switch (account) {
            case "A":
//                String linkId = purchaseProcessDao.getLinkId();
                String linkId = purchaseProcessDao.getLinkIdByOrgId(orgId);
                if (StringUtils.isEmpty(linkId)) {
//                    throw GlobalException.build("联汇暂未绑卡！");
                    linkId = "";
                }
                return purchaseProcessDao.getCustomerAccountNumberByCustomerId(linkId);
            case "B":
                String orgUid = purchaseProcessDao.getAccountUidByOrgId(orgId);
                if (StringUtils.isEmpty(orgUid)) {
                    throw GlobalException.build("机构暂未开户");
                }
                return purchaseProcessDao.getCustomerAccountNumberByCustomerId(orgUid);
            default:
                throw GlobalException.build("机构账户配置错误！");
        }
    }

    /**
     * 根据机构和费用类型查询分账配置账号id
     *
     * @param type  见FeeConstants
     * @param orgId 机构id
     */
    @Override
    public String getCustomerIdByFeeTypeAndOrdId(String type, String orgId, Integer payMode) throws GlobalException {
        String account = purchaseProcessDao.getAccountByFeeTypeAndOrdId(type, orgId);
        if (StringUtils.isEmpty(account)) {
            purchaseProcessDao.insertAcsOrgDefaultConfig(orgId);
            account = purchaseProcessDao.getAccountByFeeTypeAndOrdId(type, orgId);
        }
        switch (account) {
            case "A":
                String linkId = "";
                if (payMode == 2) {
                    linkId = purchaseProcessDao.getLinkIdByOrgId(orgId);
                } else if (payMode == 3) {
                    linkId = purchaseProcessDao.getLinkIdByLinkOrg("linker");
                }

                if (StringUtils.isEmpty(linkId)) {
                    throw GlobalException.build("联汇暂未开户");
                }
                return linkId;
            case "B":
                String orgUid = purchaseProcessDao.getAccountUidByOrgId(orgId);
                if (StringUtils.isEmpty(orgUid)) {
                    throw GlobalException.build("机构暂未开户");
                }
                return orgUid;
            case "C":
                // 平台营销资金账户
                return "#yunBizUserId_B2C#";
            default:
                throw GlobalException.build("机构账户配置错误！");
        }
    }

    /**
     * 根据费用类型，获得账户类型ABC
     *
     * @param type
     * @param orgId
     * @return
     */
    @Override
    public String getAccountTypeByFeeTypeAndOrgId(String type, String orgId) {
        String accountType = purchaseProcessDao.getAccountTypeByFeeTypeAndOrgId(type, orgId);
        if (StringUtils.isEmpty(accountType)) {
            purchaseProcessDao.insertAcsOrgDefaultConfig(orgId);
            accountType = purchaseProcessDao.getAccountTypeByFeeTypeAndOrgId(type, orgId);
        }
        return accountType;
    }

    /**
     * 生成account数据
     *
     * @param name
     * @param amount
     * @param orgId
     * @return
     * @throws GlobalException
     */
    @Override
    public AccountInfo getAccountMap(String name, Integer amount, String orgId, Integer payMode) throws GlobalException {
        AccountInfo accountInfo = new AccountInfo();
        accountInfo.setName(name);
        accountInfo.setCustomerId(this.getCustomerIdByFeeTypeAndOrdId(name, orgId, payMode));
//        if (accountInfo.getCustomerId().length() == 5) {
//            String uid = purchaseProcessDao.getAccountUidByOrgId(accountInfo.getCustomerId());
//            accountInfo.setCustomerId(uid);
//        }
//        accountInfo.setAccount(purchaseProcessDao.getCustomerAccountNumberByCustomerId(accountInfo.getCustomerId()));
        accountInfo.setAmount(amount);
        accountInfo.setType(this.getAccountTypeByFeeTypeAndOrgId(name, orgId));
        return accountInfo;
    }

    /**
     * 生成微信支付调用参数
     */
    @Override
    public Map<String, Object> getWxPayParam(String openId, String orderSn, String totalFee, String orgId, boolean needShare) {
        String notifyUrl = systemProperties.getScrmUrl() + "acs/paycallbackforwx";
        String wcpayType = "STEPLINK_" + orgId;
//        String wcpayType = "STEPLINK_10012";
//        openId = "ogqK9wBaFYIGybjJPXcmnymcNEJg";
        Map<String, String> params = new HashMap<>();
        params.put("body", "step商城订单");
        params.put("notifyUrl", notifyUrl);
        params.put("openid", openId);
        params.put("outTradeNo", orderSn);
        params.put("timestamp", String.valueOf(System.currentTimeMillis()));
        params.put("totalFee", totalFee);
        params.put("tradeType", "JSAPI");
        params.put("wcpayType", wcpayType);
        if (systemProperties.isWxSplit()) {
            params.put("needShare", "1");
        }
//        params.put("needShare", needShare ? "1" : "0");
        Map<String, String> appSign = ParamSignUtils.sign(params);
        params.put("appSign", appSign.get("appSign"));
        LOGGER.info("paymsg=================" + params);
        return new HashMap<>(params);
    }

    @Override
    public String getCustomerIdByTokenAndOpenid(Map<String, Object> param) {
        return purchaseProcessDao.getCustomerIdByTokenAndOpenid(param);
    }

    @Override
    public void payCallBackForWx(Map<String, Object> param) throws Exception {
        String transactionId = (String) param.get("transactionId");//商户订单号
        String outTradeNo = (String) param.get("outTradeNo");//商户订单号
        String totalFee = (String) param.get("totalFee");//订单金额
        Map<String, Object> map = new HashMap<>();
        map.put("orderSn", outTradeNo);
        map.put("txsn", transactionId);
        map.put("status", "20");
        map.put("totalFee", totalFee);
        this.payCallback(map);
    }

    private void zeroBuy(String orderSn) throws UnsupportedEncodingException {
        Map<String, Object> map = new HashMap<>();
        map.put("orderSn", orderSn);
        map.put("txsn", "");
        purchaseProcessNewService.shopCallback(map);
    }

    @Override
    public void setTemplateMessageList(Map data) {
    }

    /**
     * 根据orderSn 进行金额下发
     *
     * @param orderSn
     */
    @Async
    @Override
    public void signalAgentPay(String orderSn, String orgid) {
        LOGGER.info("signalAgentPay===[{}]", orderSn);
        LOGGER.info("orgid===》", orgid);
        String[] split = orderSn.split(",");
        for (String sn : split) {
            String paySn = "";
            String orgId = orgid;
            String goodsType = "other";
            if (StringUtils.isEmpty(sn)) {
                continue;
            }
            if (StringUtils.isEmpty(orgId)) {
                // 商品
                orgId = purchaseProcessDao.getOrgIdByOrderSn(sn);
                if (!StringUtils.isEmpty(orgId)) {
                    //orgId不是空则是商品,获取支付paysn
                    paySn = purchaseProcessDao.getPaySnByOrderSn(sn);
                    goodsType = "goods";
                    if (StringUtils.isEmpty(paySn)) {
                        continue;
                    }
                }
                if (StringUtils.isEmpty(orgId)) {
                    // 活动
                    orgId = purchaseProcessDao.getOrgIdByEnrollOrderSn(sn);
                    if (StringUtils.isEmpty(orgId) && (sn.startsWith("Y") || sn.startsWith("I"))) {
                        //表单(积分商城)
                        orgId = purchaseProcessDao.getOrgIdByFormOrderSn(sn);
                    }
                }
                if (StringUtils.isEmpty(orgId)) {
                    // vip
                    orgId = purchaseProcessDao.getOrgIdByVipOrderSn(sn);
                }
            }
            if (StringUtils.isEmpty(orgId)) {
                continue;
            }

            Integer payMode = mallService.getPayModeByOrgId(orgId);
            if (payMode != 2 && payMode != 3) {
                continue;
            }
            String alias = "";
            if (payMode == 3) {
                alias = maiBaoLaService.getAliasByLinker();
            }
            if (payMode == 2) {
                alias = maiBaoLaService.getAlias(orgId);
            }
            if (StringUtils.isEmpty(alias)) {
                continue;
            }
            //不是商品（直接全订单下发）
            if (!"goods".equals(goodsType)) {
                this.signalAgentPayAll(alias, sn);
            } else {
                //新表是否有数据（后面可以去掉）
                Integer count = purchaseProcessDao.getProtectGoodsCount(sn);
                //商品走部分下发
                if (count > 0) {
                    this.signalAgentPayPart(alias, sn, paySn, orgId, payMode);
                } else {
                    //兼容之前的,orderSn就是paySn
                    this.signalAgentPayAll(alias, paySn);
                }

            }
        }
    }

    @Override
    public void signalAgentPayAll(String alias, String sn) {
        String url = wcPayProperties.getAcsurl() + TlPayConstant.TRADE_SIGNAL_AGENT_PAY;
        Map<String, Object> map = new HashMap<>();
        map.put("clintType", alias);
        map.put("orderSn", sn);
        int i = 0;
        while (true) {
            if (i > 5) {
                LOGGER.warn("下发超过次数限制" + sn);
                break;
            }
            try {
                LOGGER.info("request===[{}]", JSON.toJSONString(map));
                String result = httpService.doPost(url, JSON.toJSONString(map), WcPayConstant.JSON);
                LOGGER.info("result===[{}]", result);
                Map parse = (Map) JSONObject.parse(result);
                Map data = (Map) parse.get("data");
                if ("30".equals(data.get("status")) || "20".equals(data.get("status"))) {
                    break;
                }
            } catch (Exception e) {
                LOGGER.error("通联接口调用异常", e);
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ignored) {

            }
            i++;
        }
    }

    @Override
    public void signalAgentPayPart(String alias, String sn, String paySn, String orgId, Integer payMode) {
        //下发账单列表
//        String splitItems = this.getSplitItems(sn, orgId, payMode);
        Map items = this.getSplitItems(sn, orgId, payMode);
        String splitItems = "";
        if (!StringUtils.isEmpty(items.get("splitItems"))) {
            splitItems = items.get("splitItems").toString();
        }
//        String balanceItems = "";
//        if(!StringUtils.isEmpty(items.get("balanceItems"))){
//            balanceItems = items.get("balanceItems").toString();
//        }
        LOGGER.info("下发账单列表splitItems-->  " + splitItems);
        if (StringUtils.isEmpty(splitItems)) {
            LOGGER.info("下发账单列表-->splitItems为空");
            return;
        }
        String url = wcPayProperties.getAcsurl() + TlPayConstant.TRADE_SIGNAL_AGENT_PAY_PART;
        Map<String, Object> map = new HashMap<>();
        map.put("clintType", alias);
        map.put("orderSn", paySn);
        map.put("subOrderSn", sn);
        map.put("splitItems", splitItems);
        int i = 0;
        while (true) {
            if (i > 5) {
                LOGGER.warn("下发超过次数限制" + sn);
                break;
            }
            try {
                LOGGER.info("request===[{}]", JSON.toJSONString(map));
                String result = httpService.doPost(url, JSON.toJSONString(map), WcPayConstant.JSON);
                LOGGER.info("result===[{}]", result);
                Map parse = (Map) JSONObject.parse(result);
                if ("200".equals(parse.get("code"))) {
                    //通联有返回则跳出（循环避免通联）
                    break;
                }
                Map data = (Map) parse.get("data");
                if ("30".equals(data.get("status")) || "20".equals(data.get("status"))) {
                    break;
                }
            } catch (Exception e) {
                LOGGER.error("通联接口调用异常", e);
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ignored) {

            }
            i++;
        }
        /*****************     金币不用下发   *********************************/
//        if(!StringUtils.isEmpty(balanceItems)){
//            Map<String, Object> mapb = new HashMap<>();
//            mapb.put("clintType", alias);
//            mapb.put("orderSn", paySn);
//            mapb.put("subOrderSn", sn);
//            mapb.put("splitItems", balanceItems);
//            int j = 0;
//            while (true) {
//                if (j > 5) {
//                    LOGGER.warn("下发超过次数限制" + sn);
//                    break;
//                }
//                try {
//                    LOGGER.info("request===[{}]", JSON.toJSONString(mapb));
//                    String result = httpService.doPost(url, JSON.toJSONString(mapb), WcPayConstant.JSON);
//                    LOGGER.info("result===[{}]", result);
//                    Map parse = (Map) JSONObject.parse(result);
//                    Map data = (Map) parse.get("data");
//                    if ("30".equals(data.get("status"))  || "20".equals(data.get("status"))) {
//                        break;
//                    }
//                } catch (Exception e) {
//                    LOGGER.error("通联接口调用异常", e);
//                }
//                try {
//                    Thread.sleep(1000);
//                } catch (InterruptedException ignored) {
//
//                }
//                j++;
//            }
//        }
    }

    @Override
    public Map getSplitItems(String orderSn, String orgId, Integer payMode) {
        // 根据配置读取 服务费、推荐费、联汇抽成、大b抽成分别给谁
        String orgUid = purchaseProcessDao.getAccountUidByOrgId(orgId);
        List<Map<String, Object>> splitItems = new ArrayList<>();
        List<Map<String, Object>> tlParamList = purchaseProcessDao.getTlParamList(orderSn);
        Map<String, Object> splitItemIncome = new HashMap<>();
        Map<String, Object> splitItemIncomeg = new HashMap<>();
        List<AccountInfo> subAccountList = new ArrayList<>();
        Map<String, Integer> subAccountMap = new HashMap<>();
        Map<String, Integer> subAccountMapg = new HashMap<>();
        String mallsBelongId = "";
        String mallsBelongUid = "";
        String mallsOrgId = orgId;
        String mallsOrgUid = orgUid;
        // 小b和大b要去查uid
        String belongUid = "";
        for (Map tlParam : tlParamList) {
            Integer tradeType = -1;
            if (tlParam.get("tradeType") != null) {
                tradeType = Integer.valueOf(tlParam.get("tradeType").toString());
            }
            Integer amount = 0;
            if (tlParam.get("amount") != null) {
                amount = Integer.valueOf(tlParam.get("amount").toString());
            }
            Integer score = 0;
            if (tlParam.get("score") != null) {
                score = Integer.valueOf(tlParam.get("score").toString());
                amount = amount - score;
            }
            Integer amountType = 0;
            if (tlParam.get("amountType") != null) {
                amountType = Integer.valueOf(tlParam.get("amountType").toString());
            }
            String belongId = "";
            if (!StringUtils.isEmpty(tlParam.get("belongId"))) {
                belongId = tlParam.get("belongId").toString();
            }
            String receiveUser = "";
            if (!StringUtils.isEmpty(tlParam.get("receiveUser"))) {
                receiveUser = tlParam.get("receiveUser").toString();
            }
            String payUser = "";
            if (!StringUtils.isEmpty(tlParam.get("payUser"))) {
                payUser = tlParam.get("payUser").toString();
            }
            Long mallsGoodsId = null;
            if (!StringUtils.isEmpty(tlParam.get("mallsGoodsId"))) {
                mallsGoodsId = Long.valueOf(tlParam.get("mallsGoodsId").toString());
            }
            if (!StringUtils.isEmpty(mallsGoodsId)) {
                mallsOrgId = purchaseProcessDao.getOrgIdByGoodsId(mallsGoodsId);
                mallsBelongId = purchaseProcessDao.getBelongIdByGoodsId(mallsGoodsId);
            }
            if (!StringUtils.isEmpty(mallsOrgId) && !mallsOrgId.equals(orgId)) {
                mallsOrgUid = purchaseProcessDao.getAccountUidByOrgId(mallsOrgId);
            }
            if (StringUtils.isEmpty(belongUid) && !StringUtils.isEmpty(belongId)) {
                belongUid = purchaseProcessDao.getAccountUidByCustomerId(belongId);
            }
            if (StringUtils.isEmpty(mallsBelongUid) && !StringUtils.isEmpty(mallsBelongId)) {
                mallsBelongUid = purchaseProcessDao.getAccountUidByCustomerId(mallsBelongId);
            }
            if (tradeType.equals(TradeTypeConstants.RECOMMENDS_FEE)) {
                Integer mapAmount = 0;
                if (!StringUtils.isEmpty(subAccountMap.get(FeeConstants.RECOMMEND_FEE))) {
                    mapAmount = subAccountMap.get(FeeConstants.RECOMMEND_FEE);
                }
                //推荐
                subAccountMap.put(FeeConstants.RECOMMEND_FEE, mapAmount + amount);
            } else if (tradeType.equals(TradeTypeConstants.SERVER_FEE)) {
                Integer mapAmount = 0;
                if (!StringUtils.isEmpty(subAccountMap.get(FeeConstants.SERVICE_FEE))) {
                    mapAmount = subAccountMap.get(FeeConstants.SERVICE_FEE);
                }
                //服务
                subAccountMap.put(FeeConstants.SERVICE_FEE, mapAmount + amount);
            } else if (tradeType.equals(TradeTypeConstants.GOODS_PLATFORM_FEE)) {
                Integer mapAmount = 0;
                if (!StringUtils.isEmpty(subAccountMap.get(FeeConstants.ORG_DRAW_FEE))) {
                    mapAmount = subAccountMap.get(FeeConstants.ORG_DRAW_FEE);
                }
                //平台
                subAccountMap.put(FeeConstants.ORG_DRAW_FEE, mapAmount + amount);
            } else if (tradeType.equals(TradeTypeConstants.PAY_CENTAGE_FEE)) {
                Integer mapAmount = 0;
                if (!StringUtils.isEmpty(subAccountMapg.get(FeeConstants.ORG_DRAW_FEE))) {
                    mapAmount = subAccountMapg.get(FeeConstants.ORG_DRAW_FEE);
                }
                //支付抽成（大b）
                subAccountMapg.put(FeeConstants.ORG_DRAW_FEE, mapAmount + amount);
            } else if (tradeType.equals(TradeTypeConstants.GOODS_LINK_PLATFORM_FEE)) {
                Integer mapAmount = 0;
                if (!StringUtils.isEmpty(subAccountMapg.get(FeeConstants.LINK_DRAW_FEE))) {
                    mapAmount = subAccountMapg.get(FeeConstants.LINK_DRAW_FEE);
                }
                //联汇
                subAccountMapg.put(FeeConstants.LINK_DRAW_FEE, mapAmount + amount);
            } else if (tradeType.equals(TradeTypeConstants.CREATE_FEE)) {
                Integer mapAmount = 0;
                if (!StringUtils.isEmpty(subAccountMap.get(FeeConstants.ORIGINAL_FEE))) {
                    mapAmount = subAccountMap.get(FeeConstants.ORIGINAL_FEE);
                }
                //创作
                subAccountMap.put(FeeConstants.ORIGINAL_FEE, mapAmount + amount);
            } else if (tradeType.equals(TradeTypeConstants.PURCHASE_FEE)) {
                //采购
                Integer mapAmount = 0;
                if (!StringUtils.isEmpty(splitItemIncome.get("amount"))) {
                    mapAmount = (Integer) splitItemIncome.get("amount");
                }
//                splitItemIncome.put("bizUserId", (StringUtils.isEmpty(belongId)) ? orgUid : belongUid);
                splitItemIncome.put("customerId", (StringUtils.isEmpty(belongId)) ? orgUid : belongUid);
                splitItemIncome.put("amount", (mapAmount - amount));
            } else if (tradeType.equals(TradeTypeConstants.SPREAD_FEE)) {
                //推广佣金
                Integer mapAmount = 0;
                if (!StringUtils.isEmpty(splitItemIncome.get("amount"))) {
                    mapAmount = (Integer) splitItemIncome.get("amount");
                }
                Integer mapAmountg = 0;
                if (!StringUtils.isEmpty(splitItemIncomeg.get("amount"))) {
                    mapAmountg = (Integer) splitItemIncomeg.get("amount");
                }

                //销售商
//                splitItemIncome.put("bizUserId", (StringUtils.isEmpty(belongId)) ? orgUid : belongUid);
                splitItemIncome.put("customerId", (StringUtils.isEmpty(belongId)) ? orgUid : belongUid);
                splitItemIncome.put("amount", (mapAmount + amount));

                //供货商
//                splitItemIncomeg.put("bizUserId", StringUtils.isEmpty(mallsBelongId) ? orgUid : mallsBelongUid);
                splitItemIncomeg.put("customerId", StringUtils.isEmpty(mallsBelongId) ? mallsOrgUid : mallsBelongUid);
                splitItemIncomeg.put("amount", (mapAmountg - amount - score));

            } else if (tradeType.equals(TradeTypeConstants.TRADE_SERVER_FEE)) {
                //交易手续费
                Integer mapAmount = 0;
                if (!StringUtils.isEmpty(splitItemIncome.get("amount"))) {
                    mapAmount = (Integer) splitItemIncome.get("amount");
                }
                Integer mapAmountg = 0;
                if (!StringUtils.isEmpty(splitItemIncomeg.get("amount"))) {
                    mapAmountg = (Integer) splitItemIncomeg.get("amount");
                }


                if ((!StringUtils.isEmpty(belongId) && !belongId.equals(payUser)) || (StringUtils.isEmpty(belongId) && !orgId.equals(payUser))) {
                    //供货商(大b供货商)
//                    splitItemIncomeg.put("bizUserId", mallsBelongUid);
                    splitItemIncomeg.put("customerId", StringUtils.isEmpty(mallsBelongUid) ? mallsOrgUid : mallsBelongUid);
                    splitItemIncomeg.put("amount", (mapAmountg - amount));
                } else {
                    //普通商品
//                    splitItemIncome.put("bizUserId", (StringUtils.isEmpty(belongId)) ? orgUid : belongUid);
                    splitItemIncome.put("customerId", (StringUtils.isEmpty(belongId)) ? orgUid : belongUid);
                    splitItemIncome.put("amount", (mapAmount - amount));
                }

            } else if (tradeType.equals(TradeTypeConstants.REJUVENATE_FEE)) {
                //返润佣金
                Integer mapAmount = 0;
                if (!StringUtils.isEmpty(splitItemIncome.get("amount"))) {
                    mapAmount = (Integer) splitItemIncome.get("amount");
                }

//                splitItemIncome.put("bizUserId", (StringUtils.isEmpty(belongId)) ? orgUid : belongUid);
                splitItemIncome.put("customerId", (StringUtils.isEmpty(belongId)) ? orgUid : belongUid);
                splitItemIncome.put("amount", (mapAmount - amount));
            }

            if (tradeType.equals(TradeTypeConstants.DEAL_FEE) || tradeType.equals(TradeTypeConstants.DEAL_PLATFORM_FEE)) {
                //大小b商品收益，金币服务费
                if (amountType == 1) {
                    Integer mapAmount = 0;
                    if (!StringUtils.isEmpty(splitItemIncome.get("amount"))) {
                        mapAmount = (Integer) splitItemIncome.get("amount");
                    }
                    Integer mapAmountg = 0;
                    if (!StringUtils.isEmpty(splitItemIncomeg.get("amount"))) {
                        mapAmountg = (Integer) splitItemIncomeg.get("amount");
                    }

                    if ((!StringUtils.isEmpty(belongId) && !belongId.equals(receiveUser)) || (StringUtils.isEmpty(belongId) && !orgId.equals(receiveUser))) {
                        //供货商的商品收益
//                        splitItemIncomeg.put("bizUserId", (tradeType.equals(TradeTypeConstants.DEAL_PLATFORM_FEE) || StringUtils.isEmpty(mallsBelongId)) ? orgUid : mallsBelongUid);
                        splitItemIncomeg.put("customerId", StringUtils.isEmpty(mallsBelongId) ? mallsOrgUid : mallsBelongUid);
                        splitItemIncomeg.put("amount", (mapAmountg + amount));
                    } else {
                        //销售商商品收益或者普通商品收益
//                        splitItemIncome.put("bizUserId", (tradeType.equals(TradeTypeConstants.DEAL_PLATFORM_FEE) || StringUtils.isEmpty(belongId)) ? orgUid : belongUid);
                        splitItemIncome.put("customerId", StringUtils.isEmpty(belongId) ? orgUid : belongUid);
                        splitItemIncome.put("amount", (mapAmount + amount));
                    }
                    if (tradeType.equals(TradeTypeConstants.DEAL_FEE)) {
//                    splitItemIncome.put("bizUserId", (tradeType == 6 || tradeType==10 || StringUtils.isEmpty(belongId)) ? orgUid : belongUid);
                        splitItemIncome.put("customerId", (tradeType == 6 || tradeType == 10 || StringUtils.isEmpty(belongId)) ? orgUid : belongUid);
                    }
                } else if (tradeType.equals(TradeTypeConstants.SERVER_SCORE) && amountType == 2) {
                    Integer mapAmount = 0;
                    if (amountType == 2 && !StringUtils.isEmpty(subAccountMap.get(FeeConstants.SERVICE_COIN_FEE))) {
                        mapAmount = subAccountMap.get(FeeConstants.SERVICE_COIN_FEE);
                    }
                    //服务(金币)
                    subAccountMap.put(FeeConstants.SERVICE_COIN_FEE, mapAmount + amount);
                }

            }
        }
        for (String s : subAccountMap.keySet()) {
            subAccountList.add(this.getAccountMap(s, subAccountMap.get(s), orgId, payMode));
        }
        for (String s : subAccountMapg.keySet()) {
            subAccountList.add(this.getAccountMap(s, subAccountMapg.get(s), mallsOrgId, payMode));
        }

        Map<String, Integer> collect = subAccountList.stream()
                .collect(Collectors.groupingBy(AccountInfo::getCustomerId, Collectors.summingInt(AccountInfo::getAmount)));
        Map<String, Object> splitItemIncomeOrg = new HashMap<>();
        collect.forEach((x, y) -> {
            if (y <= 0) {
                return;
            }
            if ("#yunBizUserId_B2C#".equals(x) || orgUid.equals(x)) {
                // 平台营销资金账户则加入到商品收益的平台费中
                Integer amount = 0;
                Integer plantAmount = 0;
                if (!StringUtils.isEmpty(splitItemIncomeOrg.get("amount"))) {
                    amount = (Integer) splitItemIncomeOrg.get("amount");
                }
                if (!StringUtils.isEmpty(splitItemIncomeOrg.get("plantAmount"))) {
                    plantAmount = (Integer) splitItemIncomeOrg.get("plantAmount");
                }
                amount = amount + y;
                if ("#yunBizUserId_B2C#".equals(x)) {
                    plantAmount = plantAmount + y;
                }
//                splitItemIncomeOrg.put("bizUserId",orgUid);
                splitItemIncomeOrg.put("customerId", orgUid);
                splitItemIncomeOrg.put("amount", amount);
                splitItemIncomeOrg.put("plantAmount", plantAmount);
            } else {
                Map<String, Object> cashSplitItem = new HashMap<>();
//                cashSplitItem.put("bizUserId", x);
                cashSplitItem.put("customerId", x);
                cashSplitItem.put("amount", y);
                cashSplitItem.put("plantAmount", 0);
                splitItems.add(cashSplitItem);
            }
        });
        Integer mapAmountg = 0;
        if (!splitItemIncomeg.isEmpty()) {
            if (!StringUtils.isEmpty(splitItemIncomeg.get("amount")) && ((Integer) splitItemIncomeg.get("amount")) > 0) {
                splitItems.add(splitItemIncomeg);
            } else if (!StringUtils.isEmpty(splitItemIncomeg.get("amount")) && ((Integer) splitItemIncomeg.get("amount")) < 0) {
                //亏损订单
                mapAmountg = (Integer) splitItemIncomeg.get("amount");
                splitItemIncomeg.put("amount", 0);
                splitItems.add(splitItemIncomeg);
                if (!StringUtils.isEmpty(splitItemIncome.get("amount")) && ((Integer) splitItemIncome.get("amount")) > 0) {
                    Integer mapAmount = (Integer) splitItemIncome.get("amount");
                    mapAmount -= mapAmountg;
                    splitItemIncome.put("amount", mapAmount);
                }
            }
        }
        if (!splitItemIncome.isEmpty()) {
            if (!StringUtils.isEmpty(splitItemIncome.get("amount")) && ((Integer) splitItemIncome.get("amount")) > 0) {
                splitItems.add(splitItemIncome);
            }
        }

        if (!splitItemIncomeOrg.isEmpty()) {
            splitItems.add(splitItemIncomeOrg);
        }
        //[{"customerId":"C20190906Bgw72a","amount":100,"plantAmount":0}，
        // {"customerId":"9aa9e48c-481f-4690-8755-b9db9b330fee","amount":100,"plantAmount":20}]
        // 现金分账明细，JSON字符串
        Map resMap = new HashMap();
        if (splitItems.size() > 0) {
            String splitItemsString = JSON.toJSONString(splitItems);
            resMap.put("splitItems", splitItemsString);
        }
/***********************************       金币不用下发       ********************************************************/
//        Map<String, Integer> collectBalance = balanceAccountList.stream()
//                .collect(Collectors.groupingBy(AccountInfo::getCustomerId, Collectors.summingInt(AccountInfo::getAmount)));
//        Map<String, Object> balanceItemIncomeOrg = new HashMap<>();
//        collectBalance.forEach((x, y) -> {
//            if (y <= 0) {
//                return;
//            }
//            if ("#yunBizUserId_B2C#".equals(x) || orgUid.equals(x)) {
//                // 平台营销资金账户则加入到商品收益的平台费中
//                Integer amount = 0;
//                Integer plantAmount = 0;
//                if (!StringUtils.isEmpty(balanceItemIncomeOrg.get("amount"))) {
//                    amount = (Integer) balanceItemIncomeOrg.get("amount");
//                }
//                if (!StringUtils.isEmpty(balanceItemIncomeOrg.get("plantAmount"))) {
//                    plantAmount = (Integer) balanceItemIncomeOrg.get("plantAmount");
//                }
//                amount = amount + y;
//                if ("#yunBizUserId_B2C#".equals(x)) {
//                    plantAmount = plantAmount + y;
//                }
////                splitItemIncomeOrg.put("bizUserId",orgUid);
//                balanceItemIncomeOrg.put("customerId", orgUid);
//                balanceItemIncomeOrg.put("amount", amount);
//                balanceItemIncomeOrg.put("plantAmount", plantAmount);
//            } else {
//                Map<String, Object> cashSplitItem = new HashMap<>();
////                cashSplitItem.put("bizUserId", x);
//                cashSplitItem.put("customerId", x);
//                cashSplitItem.put("amount", y);
//                cashSplitItem.put("plantAmount", 0);
//                balanceItems.add(cashSplitItem);
//            }
//        });
//        if (!balanceItemIncome.isEmpty()) {
//            if (!StringUtils.isEmpty(balanceItemIncome.get("amount")) && ((Integer) balanceItemIncome.get("amount")) > 0) {
//                balanceItems.add(balanceItemIncome);
//            }
//        }
//        if (!balanceItemIncomeg.isEmpty()) {
//            if (!StringUtils.isEmpty(balanceItemIncomeg.get("amount")) && ((Integer) balanceItemIncomeg.get("amount")) > 0) {
//                balanceItems.add(balanceItemIncomeg);
//            }
//        }
//        if (!balanceItemIncomeOrg.isEmpty()) {
//            balanceItems.add(balanceItemIncomeOrg);
//        }
//        if (balanceItems.size() > 0) {
//            String balanceItemsString  = JSON.toJSONString(balanceItems);
//            resMap.put("balanceItems",balanceItemsString);
//        }
        return resMap;
    }

    @Override
    public void openAccountsByOrgId(String orgId) {
        if (StringUtils.isEmpty(orgId)) {
            throw GlobalException.build("缺少参数");
        }
        Integer payMode = mallService.getPayModeByOrgId(orgId);
        String alias = "";
        if (payMode == 3) {
            alias = maiBaoLaService.getAliasByLinker();
        }
        if (payMode == 2) {
            alias = maiBaoLaService.getAlias(orgId);
        }
        if (StringUtils.isEmpty(alias)) {
            throw GlobalException.build("请先设置clintType");
        }
        String url = wcPayProperties.getAcsurl() + TlPayConstant.USER_CREATE_MEMBER;
        List<Map<String, Object>> mapList = purchaseProcessDao.listCustomerWhereHaveBindPhoneByOrgId(orgId);
        for (Map<String, Object> map : mapList) {
            map.put("source", "1");
            map.put("acctType", "WX");
            map.put("clintType", alias);
            try {
                httpService.doPost(url, JSON.toJSONString(map), WcPayConstant.JSON);
            } catch (Exception ignored) {

            }
            try {
                Thread.sleep(500);
            } catch (InterruptedException ignored) {

            }
        }
    }

    @Override
    public Map<String, Object> checkKnowledgeOrder(Map<String, Object> param) {
        String goodsId = param.get("goodsId").toString();
        return purchaseProcessDao.getGoodsInfoByGoodsId(goodsId);
    }

    /**
     * 微信退款
     *
     * @param orderSn   订单sn
     * @param reason    退款原因
     * @param refundFee 退款金额(单位分，不得大于订单总金额)
     * @return 退款单号和退款id
     */
    @Override
    public Map<String, String> refund(String orderSn, String reason, Integer refundFee, String PaySn) {
        // 调接口
        String url = wcPayProperties.getPayurl() + WcPayConstant.REFUND_WCPAY;
        Map<String, Object> orderInfo = purchaseProcessDao.getOrderInfoByOrderSn(orderSn);
        if (orderInfo == null) {
            throw GlobalException.build("找不到订单信息");
        }
        String tradeSn = (String) orderInfo.get("tradeSn");
        if (StringUtils.isEmpty(tradeSn)) {
            throw GlobalException.build("支付流水为空");
        }
        String orgId = (String) orderInfo.get("orgId");
        // 实付订单总金额
        //Integer orderAmount = (Integer) orderInfo.get("orderAmount");
        Integer orderAmount = purchaseProcessDao.getOrderAmountByPaySn(PaySn);
        if (refundFee > orderAmount) {
            throw GlobalException.build("退款金额不得大于订单总金额");
        }
        Map<String, Object> wxRefundParam = this.getWxRefundParam(orgId, PaySn, tradeSn, reason, orderAmount.toString(), refundFee.toString());
        String result;
        try {
            result = httpService.doPost(url, wxRefundParam);
        } catch (URISyntaxException | IOException e) {
            throw GlobalException.build("支付网关调用异常");
        }
        if (StringUtils.isEmpty(result)) {
            throw GlobalException.build("支付网关调用失败");
        }
        LOGGER.info("refund,result===[{}]", result);
        Map parse = (Map) JSON.parse(result);
        Integer rt = (Integer) parse.get("rt");
        String refundId = (String) parse.get("refundId");
        if (rt == null || rt == 0) {
            throw GlobalException.build("退款失败");
        }
        if (StringUtils.isEmpty(refundId)) {
            LOGGER.info("refundId未获取到");
        }
        Map<String, String> res = new HashMap<>();
        res.put("outRefundNo", (String) wxRefundParam.get("outRefundNo"));
        res.put("refundId", refundId);
        return res;
    }

    /**
     * 生成微信退款调用参数
     */
    @Override
    public Map<String, Object> getWxRefundParam(String orgId, String orderSn, String transactionId, String reason, String totalFee, String refundFee) {
        String wcpayType = "STEPLINK_" + orgId;
        Map<String, String> params = new HashMap<>();
        // outRefundNo	    商户系统内部的退款单号，商户系统内部唯一，只能是数字、大小写字母_-|*@ ，同一退款单号多次请求只	string
        String outRefundNo = TransactionOrderUtil.TYPE_REFUND + this.getUniquePrimaryKey();
        params.put("outRefundNo", outRefundNo);
        // outTradeNo	    商户订单号	string
        params.put("outTradeNo", orderSn);
        // refundDesc	    退款原因	string
        params.put("refundDesc", reason);
        // refundFee	    退款总金额，订单总金额，单位为分，只能为整数	number
        params.put("refundFee", refundFee);
        // refundFeeType	货币类型，符合ISO 4217标准的三位字母代码，默认人民币：CNY	string
        params.put("refundFeeType", "CNY");
        // timestamp	    时间戳（验证参数签名是否过期时根据这个时间戳判断）	number
        params.put("timestamp", String.valueOf(System.currentTimeMillis()));
        // totalFee	        订单总金额，单位为分，只能为整数	number
        params.put("totalFee", totalFee);
        // transactionId	微信生成的订单号，在支付通知中有返回	string
        params.put("transactionId", transactionId);
        // wcpayType	    微信支付标识(支付网关后台添加微信支付信息后生成)	string
        params.put("wcpayType", wcpayType);
        Map<String, String> appSign = ParamSignUtils.sign(params);
        // appSign	        参数签名	string
        params.put("appSign", appSign.get("appSign"));
        LOGGER.info("refundmsg=================" + params);
        return new HashMap<>(params);
    }

    /**
     * 微信退款查询
     *
     * @param orderSn     订单sn
     * @param outRefundNo 退款单号
     * @param refundId    退款Id
     * @return 退款状态： SUCCESS—退款成功 REFUNDCLOSE—退款关闭。 PROCESSING—退款处理中 CHANGE—退款异常
     */
    @Override
    public String refundQuery(String orderSn, String outRefundNo, String refundId) {
        // 调接口
        String url = wcPayProperties.getPayurl() + WcPayConstant.REFUND_WCPAY_QUERY;
        Map<String, Object> orderInfo = purchaseProcessDao.getOrderInfoByOrderSn(orderSn);
        String tradeSn = (String) orderInfo.get("tradeSn");
        if (StringUtils.isEmpty(tradeSn)) {
            throw GlobalException.build("支付流水为空");
        }
        String orgId = (String) orderInfo.get("orgId");

        Map<String, Object> wxRefundParam = this.getWxRefundQueryParam(orgId, orderSn, outRefundNo, refundId, tradeSn);
        String result;
        try {
            result = httpService.doPost(url, wxRefundParam);
        } catch (URISyntaxException | IOException e) {
            throw GlobalException.build("支付网关调用异常");
        }
        if (StringUtils.isEmpty(result)) {
            throw GlobalException.build("支付网关调用失败");
        }
        LOGGER.info("refundQuery,result===[{}]", result);
        Map parse = (Map) JSON.parse(result);
        Map object = (Map) parse.get("object");
        return (String) object.get("refundStatus");
    }

    /**
     * 生成微信退款查询调用参数
     */
    @Override
    public Map<String, Object> getWxRefundQueryParam(String orgId, String orderSn, String outRefundNo, String refundId, String transactionId) {
        String wcpayType = "STEPLINK_" + orgId;
        Map<String, String> params = new HashMap<>();
        // outRefundNo	    商户退款单号	string
        params.put("outRefundNo", outRefundNo);
        // outTradeNo	    商户订单号	string
        params.put("outTradeNo", orderSn);
        // refundId	        微信退款单号	string
        params.put("refundId", refundId);
        // timestamp	    时间戳（验证参数签名是否过期时根据这个时间戳判断）	number
        params.put("timestamp", String.valueOf(System.currentTimeMillis()));
        // transactionId	微信订单号	string
        params.put("transactionId", transactionId);
        // wcpayType	    微信支付标识(支付网关后台添加微信支付信息后生成)	string
        params.put("wcpayType", wcpayType);
        Map<String, String> appSign = ParamSignUtils.sign(params);
        // appSign	        参数签名	string
        params.put("appSign", appSign.get("appSign"));
        LOGGER.info("refundQuerymsg=================" + params);
        return new HashMap<>(params);
    }

    /**
     * 通联转账退款回调
     */
    @Override
    public void transferRefundCallBack(Map<String, Object> param) {
        String orderSn = (String) param.get("orderSn");
        if (StringUtils.isEmpty(orderSn)) {
            return;
        }

        LOGGER.info("transferRefundCallBack,orderSn===[{}]", orderSn);
        String status = (String) param.get("status");
        //退款成功
        merchantWalletDao.updateWithdrawTransferRefundInfo(orderSn, status.equals("20") ? 1 : 2);
    }

    /**
     * 通联退款回调
     */
    @Override
    public void refundCallBack(Map<String, Object> param) {
        String orderSn = (String) param.get("orderSn");
        if (StringUtils.isEmpty(orderSn)) {
            return;
        }
        // {param={moneyType=0, 金额类型0-现金1-金币
        // orderSn=E201911291811110210, 订单号
        // refundOrderSn=G202002211038317010,退款订单号
        // status=20,状态20-成功
        // totalFee=1,金额
        // txsn=202002211038323074877549272}} 流水号
        LOGGER.info("refundCallBack,orderSn===[{}]", orderSn);
        String status = (String) param.get("status");

        // do sth...
        String refundOrderSn = (String) param.get("refundOrderSn");
        if (StringUtils.isEmpty(refundOrderSn)) {
            return;
        }
        Map map = purchaseProcessDao.getRefundNum(refundOrderSn);
        if (map != null && !StringUtils.isEmpty(map.get("recId"))) {
            String recId = map.get("recId").toString();
            if (!"20".equals(status)) {
                // todo 加失败
                // 添加退款记录
                Map<String, Object> temps = new HashMap<>();
                temps.put("recId", recId);
                temps.put("remark", "到账失败");
                temps.put("status", 3);
                purchaseProcessDao.addRefundLogs(temps);
                LOGGER.info("refundCallBack===failed");
                return;
            }

            String count = "";
            if (map != null && map.get("tlRefundNum") != null) {
                count = map.get("tlRefundNum").toString();
            }

            if ("1".equals(count)) {
                String orgId = "";
                if (map.get("orgId") != null) {
                    orgId = map.get("orgId").toString();
                }
                if (map.get("recId") != null) {
                    recId = map.get("recId").toString();
                }
                String refundPhone = "";
                if (map.get("refundPhone") != null) {
                    refundPhone = map.get("refundPhone").toString();
                }
                //根据refundOrderSn查询ordersn（回调的是paySn）
                orderSn = purchaseProcessDao.getRefundOrderSn(refundOrderSn);
                //获取记录
                Map<String, Object> temps = new HashMap<>();
                temps.put("recId", recId);
                temps.put("remark", "到账成功");
                temps.put("status", 2);
                String lockKey = REFUND_ORDER_LOCK + recId;
                Long lock = stringRedisTemplate.opsForValue().increment(lockKey, 1);
                if (lock == 1) {
                    Integer refundCount = purchaseProcessDao.getRefundLogsCount(temps);
                    if (refundCount == 0) {
                        sendMsg(orgId, refundPhone, "9014", orderSn);
                        // todo 记录到账
                        // 添加退款记录
                        purchaseProcessDao.addRefundLogs(temps);
                    }
                } else {
                    stringRedisTemplate.opsForValue().set(lockKey, "2", 1, TimeUnit.HOURS);
                }
            } else if ("0".equals(count)) {
                //修改次数为1
                purchaseProcessDao.updateRefundNum(refundOrderSn);
            }
        }
    }

    /**
     * 通过机构id获取解冻时间
     */
    @Override
    public String getUnfreezeTimeByOrgId(String orgId) {
        Integer freezeTime = purchaseProcessDao.getFreezeTimeByOrgId(orgId);
        if (freezeTime == null || freezeTime < 0) {
            freezeTime = 30;
        }
        // 解冻时间
        return df.format(LocalDateTime.now()
                .plusDays(freezeTime));
    }

    /**
     * 更新状态
     */
    @Override
    public void updateProtectStatusWhereAutoConfirm(String orderSn, String unfreezeTime) {
        purchaseProcessDao.updateProtectStatusWhereAutoConfirm(orderSn, unfreezeTime);
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("orderSn", orderSn);
        param.put("endTime", unfreezeTime);
        protectRecordDao.setEndTime(param);

    }

    /**
     * 判断订单是否在退款中
     *
     * @param orderSn
     * @return true-在退款中，false-不在退款中
     */
    @Override
    public boolean judgeOrderIfInRefundByOrderSn(String orderSn) {
        return purchaseProcessDao.judgeOrderIfInRefundByOrderSn(orderSn) != 0;
    }

    //退款到账发送短信
    @Override
    public void sendMsg(String orgId, String phone, String businessType, String orderSn) {
        try {
            // 发送信息
            Map<String, Object> nvps = new HashMap<>();
            nvps.put("businessType", businessType);
            nvps.put("mobilNumber", phone);
            nvps.put("params", "{order=" + orderSn + "}");
            String result = smsService.sendMsg(orgId, nvps);
            LOGGER.info("退款操作短信发送结果===" + result);
        } catch (Exception e) {
            LOGGER.info("短信网关错误===" + e);
        }
    }

    @Async
    @Override
    public void exercise(Map<String, Object> map) {
        List<Map<String, Object>> exercise = maiBaoLaService.getExerciseByGoodsId(map.get("goodsId").toString());
        if (exercise == null || exercise.size() == 0) {
            return;
        }
        Object recId = map.get("recId");
        for (Map<String, Object> oneExercise : exercise) {
            Integer giftType = (Integer) oneExercise.get("giftType");
            if (giftType == 1) {
                // 赠送过的、已有的知识付费商品不再赠送
                String giftContent = (String) oneExercise.get("giftContent");
                Map<String, Object> purMap = new HashMap<>();
                purMap.put("goodsId", giftContent);
                String columnGoodsId = purchaseProcessDao.getColumnGoodsIdByContentGoodsId(giftContent);
                purMap.put("columnGoodsId", columnGoodsId);
                purMap.put("customerId", map.get("customerId"));
                boolean ifPurchase = columnService.ifPurchase(purMap);
                if (ifPurchase) {
                    continue;
                }
            }
            // 活动id
            Integer id = (Integer) oneExercise.get("id");
            oneExercise.put("recId", recId);
            int i = purchaseProcessDao.addExerciseById(id);
            if (i > 0) {
                // 发放数增加成功
                purchaseProcessDao.insertExerciseRecord(oneExercise);
                purchaseProcessDao.changeExerciseStateById(id);
            }
        }
    }


    /**
     * 新确认订单
     */
    @Override
    public List<CheckMerchantOrderPo> checkOrderNew(Map<String, Object> param, CouponCustomerInfo couponCustomerInfo) {
        List<CheckMerchantOrderPo> checkMerchantOrderList = new ArrayList<CheckMerchantOrderPo>();
        String customerId = (String) param.get("customerId");
        // 剩余积分
        Integer score = purchaseProcessDao.getScoreByCustomerId(customerId);
        Integer goodsId = null;
        Integer buyCount = (Integer) param.get("buyCount");
        Integer addressId;
        boolean isVip = false;
        if (param.containsKey("isVip") && !StringUtils.isEmpty(param.get("isVip")) && "1".equals(param.get("isVip").toString())) {
            isVip = true;
        }
        if (!param.containsKey("addressId") || StringUtils.isEmpty(param.get("addressId"))) {
            // 获取地址
            OrderAddressDto orderAddressDto = mallDao.getDefaultReceiveAddress(param);
            if (null == orderAddressDto || StringUtils.isEmpty(orderAddressDto.getAddressId())) {
                addressId = 0;
            } else {
                addressId = Integer.valueOf(orderAddressDto.getAddressId().toString());
            }
        } else {
            addressId = (Integer) param.get("addressId");
        }
        String shoppingCartIds = (String) param.get("shoppingCartIds");

        if (param.containsKey("goodsId") && param.get("goodsId") != null) {
            goodsId = Integer.valueOf(param.get("goodsId").toString());
            Integer quota = maiBaoLaService.quota(goodsId.toString(), customerId);
            if (quota == -3) {
                throw GlobalException.build("您不满足购买条件");
            }
            if (buyCount > quota && quota != -1) {
                String goodsName = purchaseProcessDao.getGoodsNameByGoodsId(goodsId.toString());
                throw GlobalException.build(goodsName + "商品超过了限购上限");
            }
        }
        // 3+4
//        Map<String, String> platformRateMap = purchaseProcessDao.getPlatformRateByOrgId(orgId);
//        Double linkerTake = Double.valueOf(platformRateMap.get("linkerTake"));
//        Double unionBarleyTake = Double.valueOf(platformRateMap.get("unionBarleyTake"));
//        Double platformRate = linkerTake + unionBarleyTake;
        if (goodsId != null && goodsId != 0 && buyCount != 0) {

            //计算运费
            Map<String, Object> goodsShippingFee = getGoodsShippingFee(addressId, goodsId, buyCount);
            long shippingFee = (Long) goodsShippingFee.get("fee");
            String feeTip = (String) goodsShippingFee.get("tip");
            boolean ifShippingFee = (Boolean) goodsShippingFee.get("ifShippingFee");

            CheckMerchantOrderPo orderPo = new CheckMerchantOrderPo();
            orderPo.setScore(score);
            orderPo.setScoreAble(score);
            List<ShoppingCartGoodsPo> goodsPoList = new ArrayList<>();
            long orderAmountTemp = 0L;
            Integer goodsNum = 0;
            long goodsAmount = 0L;
            long discountCent = 0L;
            Integer isVirtual = 0;
            // 直接购买联盟商家的商品，需要计算最大可抵扣积分
            ShoppingCartGoodsPo goodsPo = mallDao.checkShoppingGoodsOrder(param);
            if (null == goodsPo) {
                throw GlobalException.build("商品失效，请重新确认订单。");
            }
            if (buyCount > goodsPo.getGoodsCount()) {
                throw GlobalException.build("商品已达上限");
            }
            if (!StringUtils.isEmpty(param.get("goodsRemark"))) {
                goodsPo.setGoodsRemark(param.get("goodsRemark").toString());
            }
            isVirtual = goodsPo.getIsVirtual();
            Long goodsAmountTemp = goodsPo.getAmountCent();
            //判断是否会员
            if (isVip && null != goodsPo.getMemberAmountCent() && goodsPo.getMemberAmountCent() > 0) {
                discountCent = discountCent + (goodsPo.getAmountCent() - goodsPo.getMemberAmountCent()) * buyCount;
                goodsAmountTemp = goodsPo.getMemberAmountCent();
//                goodsPo.setAmountCent(goodsPo.getMemberAmountCent());
            }

            goodsPo.setMemberAmount(NumberUtils.fenToYuan(goodsPo.getMemberAmountCent()));
            goodsPo.setGoodsFreightStr(NumberUtils.fenToYuan(shippingFee));
            goodsPo.setShippingFeeTip(feeTip);
            goodsPo.setIfShippingFee(ifShippingFee);
            goodsPo.setGoodsFreightCent(shippingFee);
            goodsPo.setBuyCount(buyCount);
            goodsNum = goodsNum + goodsPo.getBuyCount();
            goodsAmount = goodsAmount + goodsAmountTemp * buyCount;
            orderAmountTemp = orderAmountTemp + goodsAmountTemp * buyCount;

            if (StringUtils.isEmpty(goodsPo.getBelongId()) && (Integer) param.get("type") != 1) {
                orderPo.setType(1);
            } else {
                orderPo.setType(0);
            }
            // 需要计算
            // 总
            double total = orderAmountTemp + shippingFee;
            // 商
//            double shop = orderAmountTemp;
            // 根据计算，需要实付金额不小于（1.推荐费+2.服务费+3.平台抽成+4.大麦抽成）
            // 1+2
//            String rebateStr = purchaseProcessDao.getPromotionStrRebateByGoodsId(goodsId.longValue());
//            Double rebate = Double.valueOf(rebateStr);
//            // 计算
//            double v = total - (shop * rebate) / (100 - platformRate);

            // 可用积分只舍不入
            int i = (int) total;
            if (score > i) {
                orderPo.setScoreAble(i);
            }
            goodsPoList.add(goodsPo);
            orderAmountTemp = orderAmountTemp + shippingFee;
//            orderPo.setGoodsAmount(new BigDecimal(Math.round(goodsAmount) / 100.0).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
//            orderPo.setOrderAmount(new BigDecimal(Math.round(orderAmountTemp) / 100.0).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
//            orderPo.setOrderTotalPrice(new BigDecimal(Math.round(orderAmountTemp) / 100.0).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
            orderPo.setGoodsAmount((goodsAmount / 100.00));
            orderPo.setOrderAmount((orderAmountTemp / 100.00));
            orderPo.setOrderTotalPrice((orderAmountTemp / 100.00));
            orderPo.setOrderTotalPriceTemp(orderAmountTemp);
            orderPo.setGoodsNum(goodsNum);
            orderPo.setShippingFee((shippingFee / 100.00));
//            orderPo.setShippingFee(new BigDecimal(Double.valueOf(shippingFee)).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());

            orderPo.setShippingFeeStr(NumberUtils.fenToYuan(shippingFee));
            orderPo.setShippingFeeTip(feeTip);
            orderPo.setIfShippingFee(ifShippingFee);
            orderPo.setIsVirtual(isVirtual);
            if (goodsPoList.size() > 0) {
                orderPo.setGoodsList(goodsPoList);
            }
            //商户id
            Map<String, Object> merchantMap = mallDao.getMerchantIdByGoodsId(goodsId.toString());
            Long merchantId = null;
            if (null != merchantMap.get("merchantId")) {
                merchantId = Long.valueOf(merchantMap.get("merchantId").toString());
            }
            String storeName = merchantMap.get("storeName").toString();
            orderPo.setMerchantId(merchantId);
            orderPo.setMerchantCustomerId(merchantMap.get("merchantCustomerId").toString());
            orderPo.setStoreName(storeName);
            orderPo.setDiscountCent(discountCent);
            orderPo.setDiscount(NumberUtils.fenToYuan(discountCent));
            checkMerchantOrderList.add(orderPo);
        } else if (!StringUtils.isEmpty(shoppingCartIds)) {
            // 购物车购买
            //根据商户来区分
            List<Map> merchantMaps = purchaseProcessDao.getMerchantByCartIds(shoppingCartIds);
            int ableAmount = score;
            if (merchantMaps != null && merchantMaps.size() > 0) {
                for (Map map : merchantMaps) {
                    long discountCent = 0L;
                    List<ShoppingCartGoodsPo> goodsPoList = new ArrayList<>();
                    long orderAmountTemp = 0L;
                    Integer goodsNum = 0;
                    double goodsAmount = 0.00;
                    long shippingFee = 0L;
                    String feeTip = "";
                    boolean ifShippingFee = true;

                    CheckMerchantOrderPo orderPo = new CheckMerchantOrderPo();
                    orderPo.setScore(score);
                    orderPo.setScoreAble(ableAmount);
                    Long merchantId = null;
                    if (map.get("merchantId") != null) {
                        merchantId = Long.valueOf(map.get("merchantId").toString());
                    }
                    String storeName = "";
                    if (map.get("storeName") != null) {
                        storeName = map.get("storeName").toString();
                    }
                    if (map.get("merchantCustomerId") != null) {
                        orderPo.setMerchantCustomerId(map.get("merchantCustomerId").toString());
                    }
                    if (map.get("shoppingCartIds") != null) {
                        shoppingCartIds = map.get("shoppingCartIds").toString();
                    }
                    orderPo.setMerchantId(merchantId);
                    orderPo.setStoreName(storeName);
                    List<ShoppingCartPo> shoppingCartPos;
                    orderPo.setType(1);
                    String[] split = shoppingCartIds.split(",");
                    param.put("shoppingCartIds", split);
                    shoppingCartPos = mallDao.checkShoppingCartOrder(param);
                    for (ShoppingCartPo cartPo : shoppingCartPos) {
                        for (ShoppingCartGoodsPo goodsPo : cartPo.getGoodsList()) {

                            goodsPo.setMemberAmount(NumberUtils.fenToYuan(goodsPo.getMemberAmountCent()));
                            Integer quota = maiBaoLaService.quota(goodsPo.getGoodsId().toString(), customerId);
                            if (quota == -3) {
                                throw GlobalException.build("您不满足购买条件");
                            }
                            if (goodsPo.getBuyCount() > quota && quota != -1) {
                                throw GlobalException.build(goodsPo.getGoodsName() + "商品超过了限购上限");
                            }

                            //计算运费
                            Map<String, Object> goodsShippingFee = getGoodsShippingFee(addressId, goodsPo.getGoodsId().intValue(), goodsPo.getBuyCount());
                            long shippingFeeTemp = (Long) goodsShippingFee.get("fee");
                            String feeTipTemp = (String) goodsShippingFee.get("tip");
                            boolean ifShippingFeeGoods = (Boolean) goodsShippingFee.get("ifShippingFee");

                            goodsPo.setShippingFeeTip(feeTipTemp);
                            goodsPo.setIfShippingFee(ifShippingFeeGoods);
                            goodsPo.setGoodsFreightCent(shippingFeeTemp);
                            goodsPo.setGoodsFreightStr(NumberUtils.fenToYuan(shippingFeeTemp));

                            if (!ifShippingFeeGoods && ifShippingFee) {
                                ifShippingFee = ifShippingFeeGoods;
                                feeTip = feeTipTemp;
                            }
                            shippingFee = shippingFee + shippingFeeTemp;

                            Long goodsAmountTemp = goodsPo.getAmountCent();
                            //判断是否会员
                            if (isVip && null != goodsPo.getMemberAmountCent() && goodsPo.getMemberAmountCent() > 0) {
                                discountCent = discountCent + (goodsPo.getAmountCent() - goodsPo.getMemberAmountCent()) * goodsPo.getBuyCount();
                                goodsAmountTemp = goodsPo.getMemberAmountCent();
//                                goodsPo.setAmountCent(goodsPo.getMemberAmountCent());
                            }
                            orderAmountTemp = goodsAmountTemp * goodsPo.getBuyCount() + orderAmountTemp;
                            goodsNum = goodsNum + goodsPo.getBuyCount();
                            goodsAmount = goodsAmountTemp + goodsPo.getAmount() * goodsPo.getBuyCount();
                            if (!StringUtils.isEmpty(goodsPo.getBelongId())) {
                                orderPo.setType(0);
                            }
                        }
                    }
                    if (shoppingCartPos.size() > 0) {
                        goodsPoList = shoppingCartPos.get(0).getGoodsList();
                    }
                    double v = orderAmountTemp + shippingFee;
                    if (ableAmount > v) {
                        // 可用积分不超过订单总金额
                        orderPo.setScoreAble((int) v);
                        ableAmount = ableAmount - (int) v;
                    } else {
                        ableAmount = 0;
                    }
                    orderAmountTemp = orderAmountTemp + shippingFee;
//                    orderPo.setGoodsAmount(new BigDecimal(Math.round(goodsAmount) / 100.0).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
//                    orderPo.setOrderAmount(new BigDecimal(Math.round(orderAmountTemp) / 100.0).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
//                    orderPo.setOrderTotalPrice(new BigDecimal(Math.round(orderAmountTemp) / 100.0).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                    orderPo.setGoodsAmount((goodsAmount / 100.00));
                    orderPo.setOrderAmount((orderAmountTemp / 100.00));
                    orderPo.setOrderTotalPrice((orderAmountTemp / 100.00));
                    orderPo.setOrderTotalPriceTemp(orderAmountTemp);
                    orderPo.setGoodsNum(goodsNum);
//                    orderPo.setShippingFee(new BigDecimal(Double.valueOf(shippingFee)).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                    orderPo.setShippingFee((shippingFee / 100.00));
                    orderPo.setShippingFeeStr(NumberUtils.fenToYuan(shippingFee));
                    orderPo.setIfShippingFee(ifShippingFee);
                    orderPo.setShippingFeeTip(feeTip);
                    orderPo.setDiscountCent(discountCent);
                    orderPo.setDiscount(NumberUtils.fenToYuan(discountCent));
                    if (goodsPoList.size() > 0) {
                        orderPo.setGoodsList(goodsPoList);
                    }
                    checkMerchantOrderList.add(orderPo);
                }
            }
        }
        //优惠券相关
        return this.couponH5Service.getUsableCouponList(checkMerchantOrderList, couponCustomerInfo, isVip);
    }

    @Override
    public String getOrgIdByToken(Map<String, Object> param) {
        return purchaseProcessDao.getOrgIdByToken(param);
    }

    @Override
    public String getCustomerIdByOrgIdAndOpenid(Map<String, Object> param) {
//        return purchaseProcessDao.getCustomerIdByTokenAndOpenid(param);
        return purchaseProcessDao.getCustomerIdByOrgIdAndOpenid(param);
    }

    //获取订单支付状态
    @Override
    public Map<String, Object> getOrderPayStatus(String orderSn, String payType) {
        int paySta = 0;
        String s = stringRedisTemplate.opsForValue().get(payStatusKey + orderSn);
        if (!StringUtils.isEmpty(s)) {
            paySta = 1;
        }
        Map<String, Object> res = new HashMap<>();
        res.put("payState", paySta);
        return res;
//
//        switch (payType) {
//            case "goods":
//                return purchaseProcessDao.getOrderPayStatus(orderSn);
//            case "open":
//                return purchaseProcessDao.getOpenOrderPayStatus(orderSn);
//            default:
//                throw GlobalException.build("参数错误");
//        }
    }

    //计算运费
    @Override
    public Map<String, Object> getGoodsShippingFee(Integer addressId, Integer goodsId, Integer buyCount) {
        Map<String, Object> feeMap = new HashMap<>();
        Map<String, Object> goodsInfo = purchaseProcessDao.getGoodsInfoByGoodsId(goodsId.toString());
        String templateId = (String) goodsInfo.get("freightTemplateId");
        long goodsFreight = Long.valueOf(goodsInfo.get("goodsFreight").toString());

        if (StringUtils.isEmpty(addressId) || 0 == addressId) {
            if (StringUtils.isEmpty(templateId)) {
                feeMap.put("fee", goodsFreight);
                feeMap.put("tip", "请选择地址");
                feeMap.put("ifShippingFee", true);
                feeMap.put("sta", false);
                return feeMap;
            } else {
                feeMap.put("fee", goodsFreight);
                feeMap.put("tip", "请选择地址");
                feeMap.put("ifShippingFee", false);
                feeMap.put("sta", false);
                return feeMap;
            }
        } else {
            if (StringUtils.isEmpty(templateId)) {
                feeMap.put("fee", goodsFreight);
                feeMap.put("tip", "");
                feeMap.put("ifShippingFee", true);
                feeMap.put("sta", true);
                return feeMap;
            } else {
                Map<String, Object> addDetail = purchaseProcessDao.getAddressDetail(addressId);
                addDetail.put("templateId", templateId);
                String provinceName = addDetail.get("provinceName") == null ? "" : (String) addDetail.get("provinceName");
                String cityName = addDetail.get("cityName") == null ? "" : (String) addDetail.get("cityName");
                String areaName = addDetail.get("areaName") == null ? "" : (String) addDetail.get("areaName");
                String address = "{\"provinceName\":\"" + provinceName + "\",\"cityName\":\"" + cityName + "\",\"regionName\":\"" + areaName + "\"}";
                addDetail.put("address", address);
                Map<String, Object> templateDetail = purchaseProcessDao.getTemplateDetail(addDetail);
                if (null != templateDetail) {
                    long lastNum = Long.valueOf(templateDetail.get("lastNum").toString());//首件
                    long freight = Long.valueOf(templateDetail.get("freight").toString());//运费
                    long continueNum = Long.valueOf(templateDetail.get("continueNum").toString());//续件多少件
                    long continueCost = Long.valueOf(templateDetail.get("continueCost").toString());//续件费用
                    long fee;
                    if (buyCount <= lastNum) {
                        fee = freight;
                    } else {
                        double t = Math.ceil((double) (buyCount - lastNum) / (double) continueNum);
                        double ceil = freight + continueCost * t;
                        fee = new Double(ceil).longValue();
                    }
                    feeMap.put("fee", fee);
                    feeMap.put("tip", "");
                    feeMap.put("ifShippingFee", true);
                    feeMap.put("sta", true);
                    return feeMap;
                } else {
                    feeMap.put("fee", 0L);
                    feeMap.put("tip", "该地址无法送达");
                    feeMap.put("ifShippingFee", false);
                    feeMap.put("sta", false);
                    return feeMap;
                }

            }
        }
    }

    //供货商商品减库存
    @Override
    public Integer saveMallsGoodsCount(Long goodsId, String skuId, Integer goodsNum, Long mallsGoodsId, Long mallsSkuId) {
        LOGGER.info("供货商商品减库存=goodsId:" + goodsId + ",skuId:" + skuId + ",goodsNum:" + goodsNum + ",mallsGoodsId:" + mallsGoodsId + ",mallsSkuId:" + mallsSkuId);
        int updateCount;
        if (null == goodsNum || goodsNum < 1) {
            throw GlobalException.build("至少购买一件商品");
        }
        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(LUA_SCRIPT, Long.class);

        //region 更新sku库存
        if (!StringUtils.isEmpty(skuId)) {
            String skuKey;
            Map<String, Object> mapSku = new HashMap<>();
            mapSku.put("goodsNum", goodsNum);
            if (!StringUtils.isEmpty(mallsSkuId) && mallsSkuId > 0) {
                mapSku.put("skuId", mallsSkuId);
                mapSku.put("goodsId", mallsGoodsId);
                skuKey = CrmRedisKeys.skuCountKey + mallsGoodsId + "_" + mallsSkuId;
            } else {
                mapSku.put("skuId", skuId);
                mapSku.put("goodsId", goodsId);
                skuKey = CrmRedisKeys.skuCountKey + goodsId + "_" + skuId;
            }
            Long skuResult = stringRedisTemplate.execute(redisScript, Collections.singletonList(skuKey), goodsNum.toString());
            if (null == skuResult || skuResult < 1) {
                LOGGER.warn("sku库存不足=skuId:" + skuId);
                throw GlobalException.build("该规格商品库存不足");
            }
//            updateCount = mallDao.updateSkuAllCount(mapSku);
            LOGGER.info("saveMallsGoodsCount----leftPush---decrbySkuCountList：" + JSON.toJSONString(mapSku));
            stringRedisTemplate.opsForList().leftPush("decrbySkuCountList", JSON.toJSONString(mapSku));
        }
        //endregion

        // region 更新商品库存
        String goodsKey;
        Map<String, Object> mapGoods = new HashMap<>();
        mapGoods.put("goodsNum", goodsNum);
        if (!StringUtils.isEmpty(mallsGoodsId) && mallsGoodsId > 0) {
            mapGoods.put("goodsId", mallsGoodsId);
            goodsKey = CrmRedisKeys.goodsCountKey + mallsGoodsId;
        } else {
            mapGoods.put("goodsId", goodsId);
            goodsKey = CrmRedisKeys.goodsCountKey + goodsId;
        }

        Long goodsResult = stringRedisTemplate.execute(redisScript, Collections.singletonList(goodsKey), goodsNum.toString());
        if (null == goodsResult || goodsResult < 1) {
            LOGGER.warn("商品库存不足=goodsId:" + goodsId);
            throw GlobalException.build("商品库存不足");
        }

        LOGGER.info("saveMallsGoodsCount----leftPush---decrbyGoodsCountList：" + JSON.toJSONString(mapGoods));
        stringRedisTemplate.opsForList().leftPush("decrbyGoodsCountList", JSON.toJSONString(mapGoods));
        //        updateCount = mallDao.updateGoodsAllCount(mapGoods);

        //endregion

        return 1;


//
//        LOGGER.info("供货商商品减库存=goodsId:" + goodsId + ",skuId:" + skuId + ",goodsNum:" + goodsNum + ",mallsGoodsId:" + mallsGoodsId + ",mallsSkuId:" + mallsSkuId);
//        int updateCount;
//        if(null == goodsNum || goodsNum < 1){
//            throw GlobalException.build("至少购买一件商品");
//        }
//        //更新商品库存
//        String goodsKey;
//        Map<String, Object> mapGoods = new HashMap<>();
//        mapGoods.put("goodsNum", goodsNum);
//        if(!StringUtils.isEmpty(mallsGoodsId) && mallsGoodsId > 0){
//            mapGoods.put("goodsId",mallsGoodsId);
//            goodsKey = CrmRedisKeys.goodsCountKey + mallsGoodsId;
//        }else{
//            mapGoods.put("goodsId", goodsId);
//            goodsKey = CrmRedisKeys.goodsCountKey + goodsId;
//        }
//        for (int i = 0; i < goodsNum; i++) {
//            String goodsRightPop = stringRedisTemplate.opsForList().rightPop(goodsKey);
//            if (StringUtils.isEmpty(goodsRightPop)) {
//                for (int j = 0; j < i; j++) {
//                    stringRedisTemplate.opsForList().leftPush(goodsKey, "1");
//                }
//                LOGGER.warn("商品库存不足=goodsId:" + goodsId );
//                throw GlobalException.build("商品库存不足");
//            }
//        }
//        LOGGER.info("updateGoodsAllCount------start");
//       updateCount = mallDao.updateGoodsAllCount(mapGoods);
//        LOGGER.info("updateGoodsAllCount------end");
//        //更新sku库存
//        if (updateCount > 0 && !StringUtils.isEmpty(skuId)) {
//            String skuKey;
//            Map<String, Object> mapSku = new HashMap<>();
//            mapSku.put("goodsNum", goodsNum);
//            if(!StringUtils.isEmpty(mallsSkuId) && mallsSkuId > 0){
//                mapSku.put("skuId",mallsSkuId);
//                skuKey = CrmRedisKeys.skuCountKey + mallsGoodsId + "_" + mallsSkuId;
//            }else{
//                mapSku.put("skuId",skuId);
//                skuKey = CrmRedisKeys.skuCountKey + goodsId + "_" + skuId;
//            }
//            for (int i = 0; i < goodsNum; i++) {
//                String skuRightPop = stringRedisTemplate.opsForList().rightPop(skuKey);
//                if (StringUtils.isEmpty(skuRightPop)) {
//                    for (int j = 0; j < i; j++) {
//                        stringRedisTemplate.opsForList().leftPush(skuKey, "1");
//                    }
//                    LOGGER.warn("sku库存不足:" + mapSku );
//                    throw GlobalException.build("商品库存不足");
//                }
//            }
//            updateCount = mallDao.updateSkuAllCount(mapSku);
//        }
//        return updateCount;


        /***************************原更新库存*******************************/
//        //更新主商品库存
//        Map<String, Object> mapM = new HashMap<>();
//        mapM.put("goodsId", goodsId);
//        mapM.put("goodsNum", goodsNum);
//        for (int i = 0; i < goodsNum; i++) {
//            String goodsRightPop = stringRedisTemplate.opsForList().rightPop(CrmRedisKeys.goodsCountKey + goodsId);
//            if (StringUtils.isEmpty(goodsRightPop)) {
//                for (int j = 0; j < i; j++) {
//                    stringRedisTemplate.opsForList().leftPush(CrmRedisKeys.goodsCountKey + goodsId, "1");
//                }
//                LOGGER.warn("商品库存不足=goodsId:" + goodsId );
//                throw GlobalException.build("商品库存不足");
//            }
//        }
//        updateCount = mallDao.updateGoodsCount(mapM);
//
//        //更新供货商库存
//        if (updateCount > 0 && !StringUtils.isEmpty(mallsGoodsId)) {
//            List<Map<String, Object>> mallsGoodsList = mallDao.getMallsGoodsList(mallsGoodsId, goodsId);
//            for (Map<String, Object> da : mallsGoodsList) {
//                Map<String, Object> mapM2 = new HashMap<>();
//                mapM2.put("goodsId", da.get("goodsId"));
//                mapM2.put("goodsNum", goodsNum);
//                for (int i = 0; i < goodsNum; i++) {
//                    String goodsRightPop = stringRedisTemplate.opsForList().rightPop(CrmRedisKeys.goodsCountKey + da.get("goodsId"));
//                    if (StringUtils.isEmpty(goodsRightPop)) {
//                        for (int j = 0; j < i; j++) {
//                            stringRedisTemplate.opsForList().leftPush(CrmRedisKeys.goodsCountKey + da.get("goodsId"), "1");
//                        }
//                        LOGGER.warn("商品库存不足=goodsId:" + da.get("goodsId") );
//                        throw GlobalException.build("商品库存不足");
//                    }
//                }
//                updateCount = mallDao.updateGoodsCount(mapM2);
//                if (updateCount == 0) {
//                    LOGGER.warn("商品库存不足"+JSON.toJSONString(mapM2));
//                    break;
//                }
//            }
//        }
//
//        //更新主sku库存
//        if (!StringUtils.isEmpty(skuId) && updateCount > 0) {
//            Map<String, Object> map = new HashMap<>();
//            map.put("goodsId", goodsId);
//            map.put("skuId", skuId);
//            map.put("goodsNum", goodsNum);
//            for (int i = 0; i < goodsNum; i++) {
//                String goodsSkuRightPop = stringRedisTemplate.opsForList().rightPop(CrmRedisKeys.skuCountKey + goodsId + "_" + skuId);
//                if (StringUtils.isEmpty(goodsSkuRightPop)) {
//                    for (int j = 0; j < i; j++) {
//                        stringRedisTemplate.opsForList().leftPush(CrmRedisKeys.skuCountKey + goodsId + "_" + skuId, "1");
//                    }
//                    LOGGER.warn("sku库存不足=goodsId:" + goodsId + ",skuId:" + skuId);
//                    throw GlobalException.build("商品库存不足");
//                }
//            }
//            updateCount = purchaseProcessDao.updateGoodsSkuCount(map);
//
//            //更新供货商sku库存
//            if (updateCount > 0 && !StringUtils.isEmpty(mallsGoodsId)) {
//                Map<String, Object> skuInfo = mallDao.getSkuById(skuId);
//                Long mallsSkuId = (Long) skuInfo.get("mallsSkuId");
//                if(!StringUtils.isEmpty(mallsSkuId)){
//                    List<Map<String, Object>> mallsGoodsSkuList = mallDao.getMallsGoodsSkuList(mallsSkuId, skuId);
//                    if (null != mallsGoodsSkuList && mallsGoodsSkuList.size() > 0) {
//                        for (Map<String, Object> da : mallsGoodsSkuList) {
//                            Map<String, Object> mapS = new HashMap<>();
//                            mapS.put("goodsId", da.get("goodsId"));
//                            mapS.put("goodsNum", goodsNum);
//                            mapS.put("skuId", da.get("skuId"));
//                            for (int i = 0; i < goodsNum; i++) {
//                                String goodsSkuRightPop = stringRedisTemplate.opsForList().rightPop(CrmRedisKeys.skuCountKey + da.get("goodsId") + "_" + da.get("skuId"));
//                                if (StringUtils.isEmpty(goodsSkuRightPop)) {
//                                    for (int j = 0; j < i; j++) {
//                                        stringRedisTemplate.opsForList().leftPush(CrmRedisKeys.skuCountKey + da.get("goodsId") + "_" + da.get("skuId"), "1");
//                                    }
//                                    LOGGER.warn("sku库存不足=goodsId:" + da.get("goodsId") + ",skuId:" + da.get("skuId"));
//                                    throw GlobalException.build("商品库存不足");
//                                }
//                            }
//                            updateCount = purchaseProcessDao.updateGoodsSkuCount(mapS);
//                            if (updateCount == 0) {
//                                LOGGER.warn("sku库存不足"+JSON.toJSONString(mapS));
//                                break;
//                            }
//                        }
//                    }
//                }
//            }
//        }
//        return updateCount;
        /***************************原更新库存*******************************/
    }

    @Override
    public String getUniquePrimaryKey() {
        String primaryKey = TransactionOrderUtil.getPrimaryKey();
        String cacheKey = "unique_order_id";
        Long increment = stringRedisTemplate.opsForValue().increment(cacheKey, 1);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        stringRedisTemplate.expireAt(cacheKey, calendar.getTime());
        if (null == increment) {
            increment = 0L;
        }
        return primaryKey + increment;
    }
}